Зачем нам нужен интерфейс IEqualityComparer, IEqualityComparer?

#.net #hashtable #iequalitycomparer

#.net #хеш-таблица #iequalitycomparer

Вопрос:

методы ‘Equal’ и ‘GetHashCode’ существуют в классе object, и наш тип наследует базовый класс object. в чем разница между реализацией двух методов объекта напрямую и использованием интерфейса IComparer?

если мы переопределим Equal объекта и получим hashCode и перейдем к хэш-таблице, он будет использовать метод equal переопределения?

в чем разница новой хэш-таблицы с конструктором IEqualityComparer?

Ответ №1:

IComparable Интерфейс используется, когда вам нужно иметь возможность «сортировать» объекты, и он предоставляет вам метод ( CompareTo ), который сообщает вам, являются ли два объекта < , = или > . Конструктор, который использует IEqualityComparer , позволяет вам указывать конкретный Equals / GetHashCode , который может отличаться от тех, которые определены вашим объектом. Обычно Hashtable ваш объект будет переопределен Equals и GetHashCode (или базовым object Equals и GetHashCode ).

Чтобы привести пример, стандартная строка сравнивается с учетом регистра ( "A" != "a" ), Но вы могли бы создать IEqualityComparer вспомогательный класс, чтобы иметь возможность хэшировать ваши строки без учета регистра. (технически этот класс уже присутствует в нескольких вариантах: они вызываются StringComparer.InvariantCultureIgnoreCase , и все другие статические методы StringComparer этого возвращают StringComparer объект, который реализует IComparer , IEqualityComparer , IComparer<string> , IEqualityComparer<string> )

В качестве примечания Hashtable используется IEqualityComparer необязательный параметр, а не универсальная версия IEqualityComparer<T> , потому Hashtable что это предварительные обобщения.

Ответ №2:

IComparer интерфейсы (как общий, так и не общий) позволяют сравнивать два экземпляра друг с другом.

Compare Метод позволяет сравнивать сам объект с другим экземпляром. Конечно, когда текущий экземпляр имеет значение null, NullReferenceException в этом случае вы получите a, поскольку вы вызываете Compare экземпляр ‘null’. Класс, который реализует IComparer , может преодолеть эту проблему.

Итак, когда вы реализуете интерфейс IComparer, у вас будет класс с методом ‘Compare’, который можно вызвать следующим образом:

 public class MyObjectComparer : IComparer<MyObject>
{
    public int Compare( MyObject first, MyObject second )
    {
       // implement logic here to determine whether first is less, greater or equal then second.
    }
}
  

Это позволяет вам делать это:

 var c = new MyObjectComparer();
var one = new MyObject();
var two = new MyObject();
c.Compare (one, two);
  

Когда вы создаете экземпляр a Hashtable с помощью конструктора, в котором вы указываете IEqualityComparer экземпляр, это означает, что данный IEqualityComparer ключ будет использоваться для определения того, присутствует ли определенный ключ в хеш-таблице.
В противном случае будет использоваться метод сравнения ключевого объекта.