Я хочу, чтобы мой Food
класс мог тестировать всякий раз, когда он равен другому экземпляру Food
. Позже я буду использовать его против Списка, и я хочу использовать его List.Contains()
метод. Должен ли я реализовать IEquatable<Food>
или просто переопределить Object.Equals()
? Из MSDN:
Этот метод определяет равенство с помощью средства сравнения равенства по умолчанию, как это определено реализацией объекта метода IEquatable.Equals для T (тип значений в списке).
Итак, мой следующий вопрос: какие функции / классы .NET Framework используют Object.Equals()
? Должен ли я использовать его в первую очередь?
Ответы:
Основная причина - производительность. Когда дженериков были введены в .NET 2.0 они были в состоянии добавить кучу аккуратных классов , таких как
List<T>
,Dictionary<K,V>
,HashSet<T>
и т.д. Эти структуры широко используютGetHashCode
иEquals
. Но для типов значений это обязательный бокс.IEquatable<T>
позволяет структуре реализовывать строго типизированныйEquals
метод, так что никакой упаковки не требуется. Таким образом, гораздо лучшая производительность при использовании типов значений с универсальными коллекциями.Ссылочные типы не приносят такой большой пользы, но
IEquatable<T>
реализация позволяет избежать преобразования,System.Object
которое может иметь значение, если оно вызывается часто.Как отмечается в блоге Джареда Парсона , вы все равно должны реализовать переопределения объектов.
источник
IEquatable<T>
интерфейс сделать что - нибудь больше , чем напомнить разработчик включитьpublic bool Equals(T other)
элемент в классе или структуры? Наличие или отсутствие интерфейса не имеет значения во время выполнения.Equals
Кажется, что перегрузка - это все, что необходимо.Согласно MSDN :
Таким образом, кажется, что между ними нет реальной функциональной разницы, за исключением того, что любой из них может быть вызван в зависимости от того, как используется класс. С точки зрения производительности, лучше использовать универсальную версию, потому что с ней не связаны штрафы за бокс / распаковку.
С логической точки зрения также лучше реализовать интерфейс. Переопределение объекта на самом деле никому не говорит о том, что ваш класс действительно уравновешенный. Переопределение может быть просто классом бездействия или поверхностной реализацией. Использование интерфейса явно говорит: «Эй, это действительно для проверки на равенство!» Это просто лучший дизайн.
источник
Расширяя сказанное Джошом на практическом примере. +1 Джошу - я собирался написать то же самое в своем ответе.
Таким образом, у меня есть метод Equals () многократного использования, который работает из коробки для всех моих производных классов.
источник
Если мы позвоним
object.Equals
, это заставит дорогой бокс на ценностных типах. Это нежелательно в сценариях, чувствительных к производительности. Решение заключается в использованииIEquatable<T>
.Идея
IEquatable<T>
заключается в том, что он дает тот же результат,object.Equals
но быстрее. Ограничениеwhere T : IEquatable<T>
должно использоваться с общими типами, как показано ниже.в противном случае он привязывается к
slower object.Equals()
.источник