Beim Vergleich einer Objektreferenz mit einer Zeichenkette (auch wenn die Objektreferenz auf eine Zeichenkette verweist), ist das besondere Verhalten der ==
Operator, der für die String-Klasse spezifisch ist, wird ignoriert.
Normalerweise (d. h. wenn es nicht um Zeichenketten geht), Equals
vergleicht Werte , während ==
vergleicht Objektverweise . Wenn sich zwei Objekte, die Sie vergleichen, auf genau dieselbe Instanz eines Objekts beziehen, geben beide den Wert "true" zurück, aber wenn eines denselben Inhalt hat und aus einer anderen Quelle stammt (eine separate Instanz mit denselben Daten ist), gibt nur "Equals" den Wert "true" zurück. Wie in den Kommentaren erwähnt, ist string jedoch ein Sonderfall, da es die ==
Operator, so dass bei reinen String-Referenzen (und nicht bei Objektreferenzen) nur die Werte verglichen werden, auch wenn es sich um separate Instanzen handelt. Der folgende Code veranschaulicht die feinen Unterschiede im Verhalten:
string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Console.WriteLine($"{object.ReferenceEquals(s1, s2)} {s1 == s2} {s1.Equals(s2)}");
Console.WriteLine($"{object.ReferenceEquals(s1, s3)} {s1 == s3} {s1.Equals(s3)}");
Console.WriteLine($"{object.ReferenceEquals(s1, s4)} {s1 == s4} {s1.Equals(s4)}");
Die Ausgabe ist:
True True True
False True True
False False True
4 Stimmen
Siehe auch: stackoverflow.com/questions/144530/or-equals
19 Stimmen
String-Überschreibungen
==
, aber die Operatoren sind nicht polymorph. In diesem Code ist die==
Operator wird für den Typobject
die einen Identitätsvergleich anstelle eines Wertevergleichs durchführt.25 Stimmen
Um den Kommentar von @DrewNoakes zu ergänzen: Der Compiler wählt eine
==
Überladung auf der Grundlage des Kompilierzeittyps der Operanden. DieContent
Eigenschaft istobject
. Operatoren sind nicht virtuell, so dass die Standardimplementierung von==
aufgerufen wird, was einen Vergleich der Referenzgleichheit ergibt. Bei Equals geht der Aufruf an die virtuelle Methodeobject.Equals(object)
;string
überschreibt diese Methode und führt einen ordinalen Vergleich mit dem String-Inhalt durch. Siehe msdn.microsoft.com/de-us/library/fkfd9eh8(v=vs.110).aspx y referencesource.microsoft.com/#mscorlib/system/string.cs,507 .8 Stimmen
Die Erklärung von @phoog ist präzise. Es sollte beachtet werden, dass, wenn die linke Seite von
==
hat zur Kompilierzeit den Typobject
und die rechte Seite hat zur Kompilierzeit den Typstring
dann muss der C#-Compiler die (in diesem Fall problematische) Überladungoperator ==(object, object)
; aber es wird eine Warnung zur Kompilierzeit ausgeben, dass dies unbeabsichtigt sein könnte. Also lesen die Kompilierzeit-Warnungen! Um das Problem zu beheben und trotzdem==
die linke Seite zustring
. Wenn ich mich richtig erinnere, schlägt der Warntext genau das vor.2 Stimmen
@JeppeStigNielsen +1 für den Hinweis, Compiler-Warnungen zu lesen. Noch besser: Schalten Sie die Option "Warnungen als Fehler" ein, um jeden zu zwingen, sie zu beachten.
0 Stimmen
Dies liegt an der Gleichheit der Werte (Methode equal) und der referenziellen Gleichheit (Operator ==), da die Methode equal die Werte prüft, während der Operator == die Referenz prüft.