У вас уже есть базовое определение , что они . Короче говоря, если вы реализуете IEquatable<T>
для класса T
, метод Equals
для объекта типа T
сообщает вам, равен ли сам объект (проверяемый на равенство) другому экземпляру того же самого введите T
. Принимая во внимание, что IEqualityComparer<T>
предназначен для проверки равенства любых двух экземпляров T
, обычно выходящих за рамки экземпляров T
.
Что касается то, что они означают , может сначала сбить с толку. Из определения должно быть ясно, что следовательно IEquatable<T>
(определенный в самом классе T
) должен быть стандартом де-факто для представления уникальности его объектов / экземпляров. HashSet<T>
, Dictionary<T, U>
(учитывая, что GetHashCode
также переопределяется), Contains
на List<T>
и т. Д. Используют это. Реализация IEqualityComparer<T>
на T
не помогает вышеупомянутым общим случаям. Впоследствии, есть небольшая ценность для реализации IEquatable<T>
на любом другом классе кроме T
. Это:
class MyClass : IEquatable<T>
редко имеет смысл.
С другой стороны
class T : IEquatable<T>
{
//override ==, !=, GetHashCode and non generic Equals as well
public bool Equals(T other)
{
//....
}
}
как это должно быть сделано.
IEqualityComparer<T>
может быть полезно, когда вам требуется пользовательская проверка равенства, но не как общее правило. Например, в классе Person
в какой-то момент вам может потребоваться проверить равенство двух человек в зависимости от их возраста. В этом случае вы можете сделать:
class Person
{
public int Age;
}
class AgeEqualityTester : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.Age == y.Age;
}
public int GetHashCode(Person obj)
{
return obj.Age.GetHashCode;
}
}
Чтобы проверить их, попробуйте
var people = new Person[] { new Person { age = 23 } };
Person p = new Person() { age = 23 };
print people.Contains(p); //false;
print people.Contains(p, new AgeEqualityTester()); //true
Аналогично IEqualityComparer<T>
на T
не имеет смысла.
class Person : IEqualityComparer<Person>
Правда, это работает, но не выглядит хорошо для глаз и побеждает логику.
Обычно вам нужно IEquatable<T>
. Также в идеале вы можете иметь только один IEquatable<T>
, в то время как несколько IEqualityComparer<T>
возможно на основе различных критериев.
IEqualityComparer<T>
и IEquatable<T>
в точности аналогичны Comparer<T>
и IComparable<T>
, которые используются для сравнения, а не для сравнения; хорошая тема здесь где я написал тот же ответ:)