Ja, es ist wichtig, wenn Ihr Element als Schlüssel in einem Wörterbuch verwendet werden soll, oder HashSet<T>
usw. - da dies (in Ermangelung eines benutzerdefinierten IEqualityComparer<T>
), um Elemente in Eimer zu gruppieren. Wenn der Hash-Code für zwei Elemente nicht übereinstimmt, können sie niemals als gleichwertig betrachtet werden ( Entspricht wird einfach nie aufgerufen).
El GetHashCode() Methode sollte die Equals
Logik; die Regeln sind:
- wenn zwei Dinge gleich sind (
Equals(...) == true
), dann werden sie muss den gleichen Wert zurück für GetHashCode()
- wenn die
GetHashCode()
gleich ist, ist es pas notwendig, dass sie gleich sind; dies ist eine Kollision, und Equals
wird aufgerufen, um festzustellen, ob es sich um eine echte Gleichheit handelt oder nicht.
In diesem Fall sieht es so aus: " return FooId;
" ist eine geeignete GetHashCode()
Umsetzung. Wenn Sie mehrere Eigenschaften testen, ist es üblich, sie mit Code wie unten zu kombinieren, um diagonale Kollisionen zu reduzieren (d.h. damit new Foo(3,5)
hat einen anderen Hash-Code als new Foo(5,3)
):
In modernen Rahmenwerken ist die HashCode
Typ verfügt über Methoden, die Ihnen helfen, einen Hashcode aus mehreren Werten zu erstellen; bei älteren Frameworks müssten Sie ohne auskommen, also etwas wie:
unchecked // only needed if you're compiling with arithmetic checks enabled
{ // (the default compiler behaviour is *disabled*, so most folks won't need this)
int hash = 13;
hash = (hash * 7) + field1.GetHashCode();
hash = (hash * 7) + field2.GetHashCode();
...
return hash;
}
Oh - der Einfachheit halber könnten Sie auch Folgendes anbieten ==
y !=
Operatoren beim Überschreiben Equals
y GetHashCode
.
Eine Demonstration dessen, was passiert, wenn man das falsch macht, ist aquí .