Sie haben bereits die grundlegende Definition dessen, was sie sind . Kurz gesagt, wenn Sie eine IEquatable<T>
Klasse implementieren T
, gibt die Equals
Methode für ein Objekt vom Typ an T
, ob das Objekt selbst (das auf Gleichheit getestete) einer anderen Instanz desselben Typs entspricht T
. Dient IEqualityComparer<T>
zum Testen der Gleichheit von zwei beliebigen Instanzen von T
, typischerweise außerhalb des Geltungsbereichs der Instanzen von T
.
In Bezug auf was sie sind für verwirrend auf den ersten sein. Aus der Definition sollte klar sein, dass daher IEquatable<T>
(in der Klasse T
selbst definiert) der De-facto-Standard sein sollte, um die Eindeutigkeit seiner Objekte / Instanzen darzustellen. HashSet<T>
, Dictionary<T, U>
(unter Berücksichtigung GetHashCode
wird auch überschrieben), Contains
auf List<T>
etc nutzen Sie dies. Das Implementieren IEqualityComparer<T>
auf T
hilft den oben genannten allgemeinen Fällen nicht. In der Folge gibt es wenig Wert für die Implementierung IEquatable<T>
in einer anderen Klasse als T
. Dies:
class MyClass : IEquatable<T>
macht selten Sinn.
Andererseits
class T : IEquatable<T>
{
//override ==, !=, GetHashCode and non generic Equals as well
public bool Equals(T other)
{
//....
}
}
ist, wie es gemacht werden sollte.
IEqualityComparer<T>
kann nützlich sein, wenn Sie eine benutzerdefinierte Validierung der Gleichheit benötigen, jedoch nicht in der Regel. Zum Beispiel müssen Sie in einer Klasse von Person
irgendwann die Gleichheit von zwei Personen anhand ihres Alters testen. In diesem Fall können Sie Folgendes tun:
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;
}
}
Versuchen Sie es, um sie zu testen
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
Ebenso macht IEqualityComparer<T>
on T
keinen Sinn.
class Person : IEqualityComparer<Person>
Das funktioniert zwar, sieht aber für die Augen nicht gut aus und besiegt die Logik.
Normalerweise brauchen Sie IEquatable<T>
. Idealerweise können Sie auch nur eine haben, IEquatable<T>
während mehrere IEqualityComparer<T>
nach verschiedenen Kriterien möglich sind.
Die IEqualityComparer<T>
und IEquatable<T>
sind genau analog zu Comparer<T>
und IComparable<T>
werden zu Vergleichszwecken verwendet, anstatt sie gleichzusetzen. Ein guter Thread hier, wo ich die gleiche Antwort geschrieben habe :)
EqualityComparer<T>
, die Schnittstelle zu erben, anstatt sie zu implementieren, "weil dieEqualityComparer<T>
Gleichheit mitIEquatable<T>