Das Folgende führt zu einer unendlichen Rekursion der Überladungsmethode des Operators ==
Foo foo1 = null;
Foo foo2 = new Foo();
Assert.IsFalse(foo1 == foo2);
public static bool operator ==(Foo foo1, Foo foo2) {
if (foo1 == null) return foo2 == null;
return foo1.Equals(foo2);
}
Wie überprüfe ich auf Nullen?
c#
.net
operator-overloading
Andrew Jones
quelle
quelle
Assert.IsFalse(foo2 == foo1);
foo1.Equals(foo2)
, wenn ich zum Beispielfoo1 == foo2
nur will , wennfoo1.x == foo2.x && foo1.y == foo2.y
? Ignoriert diese Antwort nicht den Fall wofoo1 != null
aberfoo2 == null
?if (foo1 is null) return foo2 is null;
In der Überladungsmethode auf Objekt umwandeln:
quelle
(object)foo1 == null
oderfoo1 == (object)null
geht zur eingebauten Überlastung==(object, object)
und nicht zur benutzerdefinierten Überlastung==(Foo, Foo)
. Es ist wie eine Überlastungsauflösung bei Methoden.Verwenden Sie
ReferenceEquals
. Aus den MSDN-Foren :quelle
Versuchen
Object.ReferenceEquals(foo1, null)
Auf jeden Fall würde ich nicht empfehlen, den
==
Bediener zu überlasten . Es sollte zum Vergleichen von Referenzen undEquals
für "semantische" Vergleiche verwendet werden.quelle
Wenn ich overrided haben
bool Equals(object obj)
und ich den Betreiber wollen==
undFoo.Equals(object obj)
die gleiche Antwort zurück, ich in der Regel die Umsetzung!=
Operator wie folgt aus :Der Bediener
==
ruft dann nach Durchführung aller Nullprüfungen für mich auf,foo1.Equals(foo2)
dass ich überschrieben habe, um die eigentliche Prüfung durchzuführen, wenn beide gleich sind.quelle
Object.Equals(Object, Object)
Seite an Seite mit ansiehtObject.ReferenceEquals(Object, Object)
, ist es ziemlich klar, dassObject.Equals(Object, Object)
alles so funktioniert, wie es in den anderen Antworten sofort vorgeschlagen wird. Warum nicht benutzen?==
Operator zu überladen , wenn Sie nur das Standardverhalten wünschen. Sie sollten nur dann überladen, wenn Sie eine benutzerdefinierte Vergleichslogik implementieren müssen, dh etwas mehr als eine Referenzgleichheitsprüfung.==
wünschenswert ist (die Frage impliziert dies), unterstütze ich diese Antwort einfach, indem ich vorschlage,Object.Equals(Object, Object)
dass andere Tricks wie die VerwendungReferenceEquals
oder explizite Besetzung unnötig sind (also "warum nicht verwenden?", "es"). SeinEquals(Object, Object)
). Auch wenn Ihr Standpunkt nicht in Beziehung steht, ist er auch richtig, und ich würde noch weiter gehen: Nur Überladung==
für Objekte, die wir als "Wertobjekte" klassifizieren können.Object.Equals(Object, Object)
wiederum Object.Equals (Object) aufgerufen wird, eine virtuelle Methode, die Foo wahrscheinlich überschreibt. Die Tatsache, dass Sie einen virtuellen Aufruf in Ihre Gleichheitsprüfung aufgenommen haben, kann sich auf die Fähigkeit des Compilers auswirken, diese Aufrufe zu optimieren (z. B. inline). Dies ist für die meisten Zwecke wahrscheinlich vernachlässigbar, aber in bestimmten Fällen können geringe Kosten in einem Gleichheitsoperator große Kosten für Schleifen oder sortierte Datenstrukturen bedeuten.Wenn Sie C # 7 oder höher verwenden, können Sie den Null-Konstanten-Mustervergleich verwenden:
Dies gibt Ihnen etwas saubereren Code als das aufrufende Objekt.ReferenceEquals (foo1, null)
quelle
public static bool operator==( Foo foo1, Foo foo2 ) => foo1?.Equals( foo2 ) ?? foo2 is null;
null
In diesem Fall gibt es tatsächlich eine einfachere Möglichkeit, dies zu überprüfen :Das ist es!
Diese Funktion wurde in C # 7 eingeführt
quelle
Mein Ansatz ist zu tun
Ich verlasse mich auf
object
den eigenen Gleichstellungsoperator, der nichts falsch machen kann. Oder eine benutzerdefinierte Erweiterungsmethode (und eine Überladung):oder um mehr Fälle zu behandeln, kann sein:
Die Einschränkung verhindert
IsNull
Werttypen. Jetzt ist es so süß wie anrufenDas heißt, ich habe einen konsistenten / nicht fehleranfälligen Stil, um durchgehend nach Nullen zu suchen. Ich habe auch festgestellt, dass
(object)item == null
es sehr, sehr, etwas schneller ist alsObject.ReferenceEquals(item, null)
, aber nur, wenn es darauf ankommt (ich arbeite gerade an etwas, bei dem ich alles mikrooptimieren muss!).Eine vollständige Anleitung zum Implementieren von Gleichstellungsprüfungen finden Sie unter "Best Practice" für den Vergleich von zwei Instanzen eines Referenztyps.
quelle
DbNull
IMO sind Fälle, in denen dies keine Probleme im Zusammenhang mit SRP verursachen würde, ziemlich selten. Nur auf den Code-Geruch hinzuweisen, könnte durchaus angebracht sein.Die statische
Equals(Object, Object)
Methode gibt an, ob zwei ObjekteobjA
undobjB
gleich sind. Sie können damit auch Objekte testen, deren Wertnull
für Gleichheit steht. Es vergleichtobjA
undobjB
für die Gleichheit wie folgt:true
. Dieser Test entspricht dem Aufruf derReferenceEquals
Methode. Wenn beidesobjA
undobjB
sindnull
, gibt die Methode außerdem zurücktrue
.objA
oderobjB
istnull
. Wenn ja, kehrt es zurückfalse
. Wenn die beiden Objekte nicht dieselbe Objektreferenz darstellen und dies auch nicht istnull
, wirdobjA.Equals(objB)
das Ergebnis aufgerufen und zurückgegeben. Dies bedeutet, dass diese Überschreibung aufgerufen wird , wennobjA
dieObject.Equals(Object)
Methode überschrieben wird..
quelle
Antworten Sie mehr auf den überschreibenden Operator, wie man ihn mit null vergleicht , der hier als Duplikat umleitet.
In den Fällen, in denen dies zur Unterstützung von Wertobjekten durchgeführt wird, finde ich die neue Notation praktisch und möchte sicherstellen, dass es nur einen Ort gibt, an dem der Vergleich durchgeführt wird. Durch die Nutzung von Object.Equals (A, B) werden auch die Nullprüfungen vereinfacht.
Dies wird == ,! =, Equals und GetHashCode überladen
Fügen Sie für kompliziertere Objekte zusätzliche Vergleiche in Equals und einen umfangreicheren GetHashCode hinzu.
quelle
Für eine moderne und komprimierte Syntax:
quelle
Schau dir das an
Referenz Richtlinien zum Überladen von Equals () und Operator ==
quelle
Sie können versuchen, eine Objekteigenschaft zu verwenden und die resultierende NullReferenceException abzufangen. Wenn die Eigenschaft, die Sie versuchen, von Object geerbt oder überschrieben wird, funktioniert dies für jede Klasse.
quelle