712 Stimmen

C# Unterschied zwischen == und Equals()

Ich habe eine Bedingung in einer Silverlight-Anwendung, die 2 Zeichenfolgen vergleicht, aus irgendeinem Grund, wenn ich verwenden == er gibt zurück falsch während .Equals() gibt zurück. wahr .

Hier ist der Code:

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
    // Execute code
}

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
    // Execute code
}

Gibt es einen Grund, warum dies geschieht?

4 Stimmen

19 Stimmen

String-Überschreibungen == , aber die Operatoren sind nicht polymorph. In diesem Code ist die == Operator wird für den Typ object 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. Die Content Eigenschaft ist object . 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 Methode object.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 .

531voto

mmx Punkte 400975

Wenn == auf einen Ausdruck des Typs object wird es sich auflösen in System.Object.ReferenceEquals .

Equals ist nur eine virtual Methode und verhält sich auch so, so dass die überschriebene Version verwendet wird (die für string Typ vergleicht den Inhalt).

442voto

BlueMonkMN Punkte 24177

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

58voto

JaredPar Punkte 699699

== y .Equals sind beide abhängig von dem im aktuellen Typ definierten Verhalten und dem aktuellen Typ am Aufrufort. Beide sind lediglich Methoden/Operatoren, die für jeden Typ überschrieben werden können und denen der Autor jedes gewünschte Verhalten zuweisen kann. Meiner Erfahrung nach ist es üblich, dass Leute Folgendes implementieren .Equals auf ein Objekt anwenden, es aber versäumen, den Operator == . Dies bedeutet, dass .Equals misst tatsächlich die Gleichheit der Werte, während == misst, ob es sich um dieselbe Referenz handelt oder nicht.

Wenn ich mit einem neuen Typ arbeite, dessen Definition noch im Fluss ist, oder wenn ich generische Algorithmen schreibe, ist die beste Vorgehensweise die folgende

  • Wenn ich Referenzen in C# vergleichen möchte, verwende ich Object.ReferenceEquals direkt (im allgemeinen Fall nicht erforderlich)
  • Wenn ich Werte vergleichen möchte, verwende ich EqualityComparer<T>.Default

In einigen Fällen, in denen ich das Gefühl habe, dass die Verwendung von == mehrdeutig ist, werde ich explizit die Object.Reference in den Code einfügen, um die Mehrdeutigkeit zu beseitigen.

Eric Lippert hat kürzlich einen Blog-Beitrag zum Thema, warum gibt es 2 Methoden der Gleichheit in der CLR. Es lohnt sich zu lesen

45voto

kashif Punkte 3513

\== Operator

  1. Wenn die Operanden Wert-Typen und ihre Werte gleich sind, wird true zurückgegeben, sonst false.
  2. Wenn die Operanden Referenztypen mit Ausnahme von string und beide beziehen sich auf denselben Instanz (dasselbe Objekt), wird true zurückgegeben, sonst false.
  3. Wenn die Operanden String Typ und ihre Werte gleich sind, wird true zurückgegeben, sonst false.

ist gleich

  1. Wenn die Operanden Referenztypen führt sie Referenz Gleichheit das heißt, wenn sich beide auf denselben Instanz (dasselbe Objekt), wird true zurückgegeben, sonst false.
  2. Wenn die Operanden Wert-Typen dann wird im Gegensatz zum == Operator geprüft, ob sie Typ und wenn ihre Typen gleich sind, wird der Operator == ausgeführt, ansonsten wird false zurückgegeben.

30voto

Liraz Shaka Amir Punkte 524

Soweit ich es verstanden habe, ist die Antwort einfach:

  1. == vergleicht Objektreferenzen.
  2. .Equals vergleicht den Objektinhalt.
  3. String Datentypen wirken immer wie ein Inhaltsvergleich.

Ich hoffe, dass ich richtig liege und dass Ihre Frage damit beantwortet ist.

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