8 Stimmen

Warum object.Equals und instanceobject.Equals nicht dasselbe sind

        string s1 = "t";
        string s2 = 't'.ToString();        

        Console.WriteLine(s1.Equals(s2)); // returning true
        Console.WriteLine(object.Equals(s1, s2)); // returning true

Hier wird das gleiche Ergebnis angezeigt. Nun, wenn ich mit StringBuilder ist es nicht den gleichen Wert zurück. Was ist der Grund dafür?

        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();

        Console.WriteLine(s1.Equals(s2)); // returning true
        Console.WriteLine(object.Equals(s1, s2)); // returning false

Bearbeiten1 : Meine obige Frage wird unten beantwortet. Aber während dieser Diskussion, was wir herausfinden, StringBuilder hat keine Überschreibung Equals Methode in seiner Implementierung. Wenn wir also StringBuilder.Equals aufrufen, geht es tatsächlich zu Object.Equals. Wenn also jemand StringBuilder.Equals und S1.Equals(S2) aufruft, wird das Ergebnis unterschiedlich sein.

1 Stimmen

Gut gefangen! Unterm Strich, StringBuilder scheint zu vergessen, die Equals(object) . Es scheint kontraintuitiv zu sein, dass Equals(StringBuilder) mit einem anderen Verhalten als Equals(object) .

7voto

Eric J. Punkte 143512

String.Equals() wird in C# überschrieben, so dass identische Zeichenketten tatsächlich Equal() wenn die Equal() Überschreibung definiert auf string verwendet wird.

Wenn Sie vergleichen String-Literale (was in Ihrem Beispiel nicht der Fall ist), ist es erwähnenswert, dass identische String-Literale interniert ... d.h. identische Zeichenketten haben dieselbe Adresse und sind daher auch über die Referenz (z.B. object.Equals() oder s1.ReferenceEquals(s2)) sowie über den Wert gleich.

StringBuilder bietet eine Überladung für Equals() die den StringBuilder als Parameter nimmt (d.h. s1.Equals(s2) wird diese Überladung aufrufen, anstatt die object.Equals(object obj) ).

http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.equals.aspx

StringBuilder.Equals() ist...

wahr, wenn diese Instanz und sb MaxCapacity-Werte haben; andernfalls ist sie falsch.

object.Equals() verwendet die static Equals() definiert für Objekt die nur auf Referenzgleichheit prüft (wenn eine Klasse übergeben wird) oder auf Wertgleichheit (wenn eine Struktur übergeben wird).

Zusammenfassend lässt sich also sagen

string s1 = "t";
string s2 = 't'.ToString();        

Console.WriteLine(s1.Equals(s2)); // true because both reference equality (interned strings) and value equality (string overrides Equals())
Console.WriteLine(object.Equals(s1, s2)); // true because of reference equality (interned strings)

StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();

Console.WriteLine(s1.Equals(s2)); // true because StringBuilder.Equals() overloaded
Console.WriteLine(object.Equals(s1, s2)); // false because the two StringBuilder instances have different addresses (references not equal)

1voto

Matt Punkte 13913

Les generische "Equals"-Methode vergleicht die Referenzen von zwei Objekten, um zu sehen, ob sie Referenz Gleichheit für Referenztypen wie StringBuilder . Für Wertetypen und string sich wie ein Wertetyp verhält (unveränderlich ist), führt er eine bitweiser Vergleich (bestimmt, ob die binäre Darstellung gleich ist). Diese Funktion ist jedoch in der Klasse StringBuilder überladen.

Nach Angaben von MSDN gibt die Methode equal des StringBuilders true zurück, wenn die folgenden Kriterien für beide StringBuilder-Objekte gleich sind:

  • Zeichenfolge
  • Kapazität
  • MaxCapacity

So scheitern s1 und s2 im zweiten Beispiel an der Referenzgleichheit, bestehen aber die benutzerdefinierte StringBuilder-Gleichheit auf der Grundlage der gerade genannten Kriterien.

1voto

competent_tech Punkte 43546

Die String-Klasse implementiert Equals so, dass sie die Werte der Strings vergleicht.

Die meisten Objektinstanzen, sofern sie nicht eine andere Art von Vergleich implementieren, prüfen, ob das Objekt Referenzen sind identisch.

Beachten Sie, dass es auch einen Fall gibt, in dem zwei verschiedene String-Konstanten, die genau denselben Wert enthalten, vom Compiler zunächst demselben Objektverweis zugewiesen werden.

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