Vous avez déjà la définition de base de ce qu'ils sont . En bref, si vous implémentez IEquatable<T>sur classe T, la Equalsméthode sur un objet de type Tvous indique si l'objet lui-même (celui qui est testé pour l'égalité) est égal à une autre instance du même type T. Considérant que, IEqualityComparer<T>sert à tester l'égalité de deux instances de T, généralement en dehors de la portée des instances de T.
Quant à savoir à quoi ils servent peut être déroutant au début. D'après la définition, il devrait être clair que par conséquent IEquatable<T>(défini dans la classe Telle - même) devrait être la norme de facto pour représenter l'unicité de ses objets / instances. HashSet<T>, Dictionary<T, U>(la considération GetHashCodeest également remplacée), Containssur List<T>etc. La mise IEqualityComparer<T>en œuvre sur Tn'aide pas les cas généraux mentionnés ci-dessus. Par la suite, il y a peu de valeur pour l'implémentation IEquatable<T>sur une autre classe que T. Ce:
class MyClass : IEquatable<T>
fait rarement sens.
D'autre part
class T : IEquatable<T>
{
//override ==, !=, GetHashCode and non generic Equals as well
public bool Equals(T other)
{
//....
}
}
c'est comment cela devrait être fait.
IEqualityComparer<T>peut être utile lorsque vous avez besoin d'une validation personnalisée de l'égalité, mais pas en règle générale. Par exemple, dans une classe de Personà un moment donné, vous devrez peut-être tester l'égalité de deux personnes en fonction de leur âge. Dans ce cas, vous pouvez faire:
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;
}
}
Pour les tester, essayez
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
De même IEqualityComparer<T>, cela Tn'a pas de sens.
class Person : IEqualityComparer<Person>
C'est vrai que cela fonctionne, mais cela ne semble pas bon aux yeux et va à l'encontre de la logique.
Ce dont vous avez généralement besoin, c'est IEquatable<T>. Idéalement aussi, vous ne pouvez en avoir qu'un IEquatable<T>alors que plusieurs IEqualityComparer<T>sont possibles en fonction de différents critères.
Les IEqualityComparer<T>et IEquatable<T>sont exactement analogues à Comparer<T>et IComparable<T>qui sont utilisés à des fins de comparaison plutôt que d'assimilation; un bon fil ici où j'ai écrit la même réponse :)
EqualityComparer<T>au lieu d'implémenter l'interface "carEqualityComparer<T>teste l'égalité à l'aide deIEquatable<T>