Oder ist es ratsam, das zu tun? Warum?Müssen die Operatoren == und! = Beim Überschreiben der Equals-Methode überschrieben werden? (.NET)
Müssen die Operatoren == und! = Beim Überschreiben der Equals-Methode überschrieben werden? (.NET)
Antwort
Siehe guidelines for overriding Equals() and operator==.
Zitat:
standardmäßig der Operator == Tests als Referenz Gleichheit durch die Bestimmung, ob zwei Referenzen auf das gleiche Objekt zeigen. Daher müssen Referenztypen den Operator == nicht implementieren, um diese Funktionalität zu erhalten. Wenn ein Typ unveränderlich ist, dh die Daten, die in der Instanz enthalten sind, nicht geändert werden können, kann das Überladen von operator == zum Vergleichen der Wertegleichheit anstelle der Referenzgleichheit nützlich sein, da sie als unveränderliche Objekte als gleich lang angesehen werden können wie sie den gleichen Wert haben. Es ist keine gute Idee, den Operator == in nicht unveränderlichen Typen zu überschreiben.
Grundsätzlich:
Wenn Sie == und wollen = verhalten wie Equals(..)
und !Equals(..)
Sie müssen die Betreiber implementieren. Sie tun das normalerweise nur mit unveränderlichen Typen.
Wenn Sie die equals-Methode überschreiben und trotzdem auf Gleichheit (oder Ungleichheit) prüfen möchten, sollten Sie wahrscheinlich auch die Methoden == und! = Überschreiben.
Es ist nicht notwendig, aber eine kluge Sache zu tun.
Wenn Sie ein Framework erstellen und ein anderer Entwickler als Sie das Objekt verwenden möchten, sollten Sie das == und! = Überschreiben. Auf diese Weise haben Entwickler, wenn sie sie benutzen, zumindest die richtige Logik, um die 2 Objekte zu vergleichen und nicht nur die gleichen im Speicher.
Ich würde sicherstellen, dass Ihre == &! = Rufen Sie Ihre equals-Methode.
Siehe Guidelines for Implementing Equals and the Equality Operator (==)
Für Werttypen (structs) „Implementieren == jedes Mal, wenn die Equals-Methode überschreiben“
Für Referenztypen (Klassen): „Die meisten Referenztypen, auch solche, die die Equals implementieren Methode, sollte nicht überschreiben ==. " Die Ausnahme ist für unveränderliche Klassen und solche mit wertähnlicher Semantik.
Es wäre ratsam, da es unerwartet wäre, wenn:
if (foo == bar)
... verhielt sich anders:
if (foo.Equals(bar))
Es gibt viele Fälle, in denen sich 'foo == bar' anders verhält als' foo.Equals (bar) '. Ein Irrglaube an ihre Äquivalenz kann leicht zu Problemen führen als die Erkenntnis, dass sie sich nicht immer gleich verhalten können und nicht erwartet werden [tatsächlich hat der Rahmen einige Ungereimtheiten in dem, was "Gleich" bedeutet, die aus einem unmotivierten Wunsch resultieren mach es passend zu '==']. – supercat
@supercat ein gutes Beispiel ist, wenn nullwertfähige Typen verglichen werden, Equals ist smart und prüft HasValue für jede Seite. – Gary
@Gary: Ich dachte mehr an Dinge wie 'Decimal'. Es ist nützlich, ein Mittel zum Vergleich zu haben, das bewertete Objekte als gleich betrachtet, wenn keines über dem anderen liegt, aber es ist auch nützlich, ein Mittel zur Gleichheitsprüfung zu haben, das gleichrangige Objekte (z. B. 1,0d und 1,00d) als verschieden erkennen kann. IMHO, solche Objekte sollten zu entgegengesetzten Vergleichsergebnissen mit '==' und '.Equals' führen. – supercat
Es ist nicht notwendig, niemand wird dich töten, wenn Sie dies nicht tun TU das.
Beachten Sie jedoch, dass es oft natürlicher ist, (A == B) als A.Equals (B) zu schreiben. Wenn Sie beide Methoden bereitstellen, wird es für die Verbraucher Ihres Codes einfacher.
Zusätzlich zu allen Antworten bereits hier, vergessen Sie nicht sicherzustellen, GetHashCode()
ist auch konsistent.
in A.Gleich (B) A kann nicht null sein in A == B kann entweder null sein
Überschreiben == um es aufzurufen Gleiches erscheint mir als eine generell schlechte Idee für Referenztypen. Wenn Sie == überschreiben, damit Equals aufgerufen wird, gibt es für einen Benutzer Ihres Codes keine Möglichkeit, zu testen, ob sich zwei Objektreferenzen auf genau dasselbe Objekt beziehen (gegenüber einem Objekt mit gleichen Eigenschaften).
Wenn Benutzer Instanzen Ihrer Klassen für Wertgleichheit testen möchten, dann sollten sie einfach Equals aufrufen und == zum Testen der Referenzgleichheit speichern.
Sie können 'Object.ReferenceEquals' verwenden, um die Referenzgleichheit zu überprüfen. –
Aha, danke Sebastian - davon wusste ich nichts. –
Obwohl es möglich ist, 'Object.ReferenceEquals' zu verwenden, ist es ziemlich klobig. Ich betrachte die C# -Benutzung des '==' -Tokens sowohl für die Overlaidable-Equality-Test- als auch für die Referenz-Equality-Test-Operatoren als einen der größten Designfehler in der Sprache. – supercat
- 1. Liste der Ruby-Operatoren, die überschrieben/implementiert werden können
- 2. Verhindern, dass die .NET-Konfigurationsdatei während der Installation überschrieben wird
- 3. C++ Operatoren überschreiben
- 4. Wie kann der Operator [] überschrieben werden?
- 5. Der! und die && Operatoren Java
- 6. Werte, die im AngularJS-Array überschrieben werden
- 7. Verhindern, dass Objekte beim Serialisieren und Deserialisieren überschrieben werden
- 8. Können lokale Änderungen beim Update von SVN immer überschrieben werden?
- 9. Welche Teile von .NET erfordern Administratorrechte, die ausgeführt werden müssen?
- 10. Sollten die Postfix-Operatoren nicht als binäre Operatoren betrachtet werden
- 11. asp.net Cookies werden überschrieben
- 12. Warum müssen die Überladungen von C# -Operatoren statisch sein?
- 13. Was tun die Operatoren '& =' und '= &'?
- 14. Wann müssen wir implizite und explizite Operatoren in C# verwenden?
- 15. Müssen Formular-Parameternamen beim POST verschlüsselt werden?
- 16. Wie können die Einstellungen HOMEBREW_CC und HOMEBREW_CXX dauerhaft überschrieben werden?
- 17. Wie kann der standardmäßige Fensterabschlussvorgang überschrieben werden?
- 18. Kann die vorherige Zeile in der Konsole überschrieben werden?
- 19. Der Abstand zwischen NAV und Jumbotron kann nicht überschrieben werden
- 20. Firebase-Daten werden überschrieben
- 21. Warum die Abfragen in der system.profile-Sammlung überschrieben werden
- 22. Kann der Boot-Complete-Konstruktor überschrieben werden?
- 23. Die endgültige Methode kann nicht von ActionBarActivity überschrieben werden
- 24. Access 2007 Locking Issue - Anlagen überschrieben werden
- 25. Operanden zum || und && Operatoren müssen in logische Skalarwerte umgewandelt werden können
- 26. Zweig: Block kann nicht in der enthaltenen Datei überschrieben werden
- 27. Meteor absoluteUrl kann nicht überschrieben werden?
- 28. Perl-Operatoren werden "entdeckt" und nicht entworfen?
- 29. Kann eine statische Methode in der abgeleiteten Klasse überschrieben werden?
- 30. In Java überladen und überschrieben
+1 Sehr klar und prägnant. –