56 Stimmen

Verständnis von IEquatable

Wenn ich Objekte implementiere, die ich mit der Methode IEquatable<T> interfaz :

  1. Warum muss ich die Equals(object) Methode, wenn ich bereits implementiert habe Equals(T) ?
  2. Kann ich die == y != Operatoren, sobald ich die IEquatable<T> ?

55voto

Ray Booysen Punkte 26896
  1. Desde MS Docs Artikel über IEquatable<T> :

    Wenn Sie die IEquatable<T> sollten Sie auch die Funktion Basisklassen-Implementierungen von Equals(Object) et GetHashCode() so dass ihr Verhalten mit dem Verhalten der Equals(T) Methode. Wenn Sie überschreiben Equals(Object) , Ihr überschriebene Implementierung wird auch in Aufrufen der statischen Equals(Object, Object) Methode für Ihre Klasse. Darüber hinaus sollten Sie die Methode op_Equality et op_Inequality Betreiber. Dadurch wird sichergestellt, dass alle Tests auf Gleichheit konsistente Ergebnisse liefern.

  2. Nein, Operatoren verwenden nicht die Equals-Methode . Sie müssen sein separat überlastet zu tun.

0 Stimmen

Wenn Sie also mit Objekten zu tun haben, wird angenommen, dass == nur die exakt gleiche Speicheradresse (dieselbe Instanz) bedeutet.

0 Stimmen

Ziemlich genau. Mehr Informationen hier: msdn.microsoft.com/de-us/library/53k8ybth(VS.80).aspx

8 Stimmen

Nein, verwenden Sie ReferenceEquals() für diesen Zweck. Der Gleichheitsoperator (==) bedeutet in der Regel dasselbe, kann aber überschrieben werden (z. B. für Strings und dergleichen).

45voto

Jon Skeet Punkte 1325502

1) Wie Ray schon sagte, überschreiben Sie Equals(object) um die Konsistenz zu gewährleisten, wenn die Methode von Klassen aufgerufen wird, die (statisch) nicht wissen, dass Sie die Methode IEquatable<T> . Zum Beispiel verwenden die nicht-generischen Sammlungsklassen Equals(object) für Vergleiche. Sie sollten auch überschreiben GetHashCode() .

2) Durchsetzung IEquatable<T> überlädt die Operatoren == und != nicht automatisch, aber es gibt nichts, was Sie daran hindert, dies zu tun, genau wie System.String tut. Sie sollten dies jedoch sehr deutlich dokumentieren, wenn Sie dies tun - und seien Sie vorsichtig, wenn Sie Vergleiche zwischen anderen Referenztypen (z.B. MyType und Object) durchführen, die immer noch den Identitätsvergleich verwenden werden. Ich vermute, dass es keine gute Idee ist, dies zu tun, es sei denn, es handelt sich um einen sehr häufig verwendeten Typ in Ihrem Code, mit dem jeder sehr vertraut sein wird. et wo der syntaktische Zucker des Überladens von == wirklich eine positive Auswirkung auf die Lesbarkeit haben wird.

1 Stimmen

Jon, gibt es irgendeinen Leistungsgewinn für einen IEquatable<T>-Implementierungstyp, der zum Beispiel in einer Collection<T> verwendet wird und die Contains-Methode aufruft?

8 Stimmen

Es wird das Gießen vermeiden, ja. Bei Werttypen wird es auch Boxing und Unboxing vermeiden. Siehe die Dokumentation für Collection<T>.Contains - es verwendet EqualityComparer<T>.Default, das die IEquatable<T>-Implementierung verwendet, wenn möglich.

6 Stimmen

Ja, es ist keine gute Idee, die Operatoren == und != zu überladen, um Wertgleichheitsprüfungen zu ermöglichen (im Gegensatz zur Standard-Referenzgleichheitsprüfung). In der MSDN-Dokumentation wird empfohlen, dies nur für unveränderliche Typen zu tun. Es gibt auch Probleme mit Schnittstellen und Operatorüberladung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X