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 .

21voto

Colonel Panic Punkte 125419

Erstens: Es gibt est einen Unterschied. Für Zahlen

> 2 == 2.0
True

> 2.Equals(2.0)
False

Und für Streicher

> string x = null;
> x == null
True

> x.Equals(null)
NullReferenceException

In beiden Fällen, == verhält sich sinnvoller als .Equals

15voto

MikeKulls Punkte 2889

Ich würde hinzufügen, dass, wenn Sie Ihr Objekt in eine Zeichenfolge, dann wird es richtig funktionieren. Aus diesem Grund gibt der Compiler eine Warnung aus:

Möglicherweise unbeabsichtigter Referenzvergleich; die linke Seite in den Typ 'string' umwandeln

7voto

Mario Levesque Punkte 956

Da die statische Version der .Equal Methode wurde bisher noch nicht erwähnt, ich möchte dies hier hinzufügen, um die 3 Varianten zusammenzufassen und zu vergleichen.

MyString.Equals("Somestring"))          //Method 1
MyString == "Somestring"                //Method 2
String.Equals("Somestring", MyString);  //Method 3 (static String.Equals method) - better

donde MyString ist eine Variable, die von einer anderen Stelle des Codes stammt.

Hintergrundinformationen und zur Sommerzeit:

In Java mit == zum Vergleich von Zeichenketten sollte nicht verwendet werden. Ich erwähne dies für den Fall, dass Sie beide Sprachen verwenden müssen und auch um Sie darauf hinzuweisen, dass die Verwendung von == kann auch durch etwas Besseres in C# ersetzt werden.

In C# gibt es keinen praktischen Unterschied für den Vergleich von Strings mit Methode 1 oder Methode 2, solange beide vom Typ String sind. Wenn jedoch eine Zeichenfolge null ist, eine Zeichenfolge von einem anderen Typ ist (z. B. ein Integer) oder eine Zeichenfolge ein Objekt mit einem anderen Verweis darstellt, kann es sein, dass der Vergleich der Inhalte auf Gleichheit nicht das Ergebnis liefert, das Sie erwarten, wie die erste Frage zeigt.

Vorgeschlagene Lösung:

Denn mit == ist nicht genau dasselbe wie die Verwendung von .Equals Wenn Sie Dinge vergleichen, können Sie die static String.Equals Methode an. Wenn die beiden Seiten nicht vom gleichen Typ sind, können Sie auf diese Weise trotzdem den Inhalt vergleichen, und wenn eine der beiden Seiten null ist, wird die Ausnahme vermieden.

   bool areEqual = String.Equals("Somestring", MyString);  

Es ist etwas aufwendiger zu schreiben, aber meiner Meinung nach sicherer in der Anwendung.

Hier sind einige Informationen, die von Microsoft kopiert wurden:

public static bool Equals (string a, string b);

Parameter

a Zeichenfolge

Die erste zu vergleichende Zeichenkette, oder null .

b Zeichenfolge

Die zweite zu vergleichende Zeichenkette, oder null .

Rückgabe Boolean

true wenn der Wert von a ist derselbe wie der Wert von b ; sonst, false . Wenn beide a y b sind null gibt die Methode true .

7voto

Ole Albers Punkte 8165

Nur als Ergänzung zu den bereits guten Antworten: Dieses Verhalten ist NICHT auf Strings oder den Vergleich verschiedener Zahlentypen beschränkt. Selbst wenn beide Elemente vom Typ Objekt desselben zugrunde liegenden Typs sind. "==" wird nicht funktionieren.

Der folgende Screenshot zeigt die Ergebnisse des Vergleichs zweier Objekt {int} - Werte

Example From VS2017

2voto

Mehmet Aras Punkte 5166

Ich bin hier etwas verwirrt. Wenn der Laufzeittyp von Content vom Typ String ist, dann sollten sowohl == als auch Equals true zurückgeben. Da dies jedoch nicht der Fall zu sein scheint, ist der Laufzeittyp von Content nicht string und der Aufruf von Equals führt eine referenzielle Gleichheit durch, was erklärt, warum Equals("Energy Attack") fehlschlägt. Im zweiten Fall jedoch wird die Entscheidung, welcher überladene statische Operator == aufgerufen werden soll, zur Kompilierzeit getroffen, und diese Entscheidung scheint ==(string,string) zu sein. Dies legt für mich nahe, dass Content eine implizite Konvertierung in string bietet.

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