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 Equals
méthode sur un objet de type T
vous 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 T
elle - 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 GetHashCode
est également remplacée), Contains
sur List<T>
etc. La mise IEqualityComparer<T>
en œuvre sur T
n'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 T
n'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>