Frage

Ich habe eine Bedingung in einer Silverlight-Anwendung, die zwei Strings vergleicht, aus irgendeinem Grund, wenn ich == verwenden es gibt false , während .Equals() kehrt true .

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 Gründe, warum dies geschieht?

War es hilfreich?

Lösung

Wenn == auf einem Ausdruck des Typs object verwendet wird, wird es beheben auf System.Object.ReferenceEquals .

Equals ist nur ein virtual Verfahren und verhält sich wie eine solche, so die überschriebene Version verwendet wird (die für string Typen vergleicht den Inhalt).

Andere Tipps

Wenn Sie ein Objekt Verweis auf eine Zeichenfolge zu vergleichen (auch wenn das Objekt Verweis auf eine Zeichenkette bezieht), das spezielle Verhalten des == Operators spezifisch auf die String-Klasse ignoriert.

Normalerweise (wenn nicht mit Strings zu tun, das ist), Equals vergleicht Werte , während == vergleicht Objektreferenzen . Wenn zwei Objekte, die Sie genau die gleiche Instanz eines Objekts beziehen vergleichen, dann werden beide wahr zurück, aber wenn man den gleichen Inhalt hat und kam aus einer anderen Quelle (eine separate Instanz mit der gleichen Daten), nur Equals Wille return true. Wie jedoch in den Kommentaren erwähnt, String ist ein Sonderfall, weil es die == Betreiber überschreibt, so dass bei rein mit String-Referenzen zu tun (und nicht den Objektreferenzen), werden nur die Werte verglichen werden, auch wenn sie separate Instanzen sind. Der folgende Code zeigt die feinen Unterschiede in Verhalten:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

Die Ausgabe lautet:

True True True
False True True
False False True

== und .Equals sind beide abhängig von dem Verhalten in der aktuellen Art und den tatsächlichen Typ an der Aufrufstelle definiert. Beide sind nur Methoden / Operatoren, die auf jeder Art außer Kraft gesetzt werden kann, und jedes Verhalten der Autor so Wünsche gegeben. Nach meiner Erfahrung, ich finde es ist üblich, dass Menschen .Equals auf einem Objekt zu implementieren, aber Vernachlässigung Operator == zu implementieren. Das bedeutet, dass .Equals tatsächlich die Gleichheit der Werte messen, während == wird messen, ob sie die gleiche Referenz.

Wenn ich mit einem neuen Typ, deren Definition gerade arbeite im Fluss oder generische Algorithmen schreiben, finde ich die beste Praxis des folgenden

ist
  • Wenn ich Referenzen in C # vergleichen will, verwende es Object.ReferenceEquals direkt (nicht im generischen Fall erforderlich)
  • Wenn ich will, Werte vergleichen I EqualityComparer<T>.Default verwenden

In einigen Fällen, wenn ich die Verwendung von == fühle, ist mehrdeutig ich ausdrücklich Object.Reference gleich im Code verwenden, um die Mehrdeutigkeit zu entfernen.

Eric Lippert hat vor kurzem eine Blog-Post über das Thema, warum gibt es zwei Methoden der Gleichheit in der CLR. Es lohnt sich die Lese

Zum einen gibt ist ein Unterschied. Für Zahlen

> 2 == 2.0
True

> 2.Equals(2.0)
False

Und für Strings

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

> x.Equals(null)
NullReferenceException

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

Ich möchte hinzufügen, dass, wenn Sie Ihr Objekt in eine Zeichenfolge, dann wird es richtig. Aus diesem Grunde wird der Compiler gibt Ihnen eine Warnung sagen:

  

Mögliche unbeabsichtigte Referenz Vergleich; Wert Vergleich zu bekommen,   wirft die linke Seite ‚string‘

eingeben

== Operator 1. Wenn Operanden Werttypen und ihre Werte gleich sind, gibt sie wahr sonst falsch. 2. Wenn Operanden Referenztypen mit Ausnahme von String und beziehen sich beide auf gleiches Objekt, gibt es wahr, sonst falsch. 3. Wenn Operanden-String-Typ und ihre Werte sind gleich, es gibt true zurück, sonst falsch.

sind

.Equals 1. Wenn Operanden Referenztypen sind, führt sie Referenz Gleichheit das ist, wenn beide auf denselben Gegenstand beziehen, es ist wahr sonst false zurück. 2. Wenn Operanden Werttypen dann anders als Operator == sind überprüft sie auf ihre Art erste und wenn ihre Typen gleich sind es führt Operator == sonst falsch er zurückkehrt.

Soweit ich es verstehe, die Antwort ist einfach:

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

Ich hoffe, ich bin richtig ist und dass es Ihre Frage beantwortet.

Da die statische Version des .Equal Methode bisher nicht erwähnt wurde, würde Ich mag diese hier hinzufügen zusammenzufassen und die drei Varianten zu vergleichen.

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

wo MyString ist eine Variable, die von woanders in dem Code kommt.

Hintergrundinformationen und summerize:

In Java == mit Zeichenfolgen zu vergleichen, sollten nicht verwendet werden. Ich erwähne dies, falls Sie beiden Sprachen verwenden müssen, und auch Sie wissen zu lassen, dass == verwendet, kann auch mit etwas besser in C # ersetzt werden.

In C # gibt es keinen praktischen Unterschied zum Vergleichen Strings Methode 1 oder Methode 2, solange beide vom Typ string sind. wenn man null ist jedoch, ist eine von einem anderen Typ (wie eine ganze Zahl ist), oder ein repräsentiert ein Objekt, das eine andere Referenz hat, dann, wie die erste Frage zeigt, können Sie erfahren, dass der Inhalt für die Gleichstellung Vergleich zurückkehren kann nicht das, was Sie erwarten.

Lösungsvorschlag:

Da == verwendet, ist nicht genau das gleiche wie .Equals verwenden, wenn die Dinge zu vergleichen, können Sie die statische String.Equals verwenden Methode statt. Auf diese Weise, wenn die beiden Seiten nicht die gleiche Art sind, werden Sie immer noch den Inhalt vergleichen und wenn man null ist, werden Sie die Ausnahme vermeiden.

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

Es ist ein wenig zu schreiben, aber meiner Meinung nach, sicherer zu verwenden.

Hier finden Sie einige Informationen von Microsoft kopiert:

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

Parameter

a String

Der erste String vergleichen oder null.

b String

Die zweite Zeichenfolge zu vergleichen, oder null.

Returns Boolean

true, wenn der Wert von a gleich dem Wert von b ist; andernfalls false. Wenn beide a und b null sind, gibt die Methode true.

Ich bin ein bisschen verwirrt hier. Wenn der Laufzeittyp des Inhalts vom Typ String ist, dann beide == und Equals sollten true zurückgeben. Da jedoch bedeutet dies nicht erscheinen, den Fall zu sein, dann Laufzeittyp des Inhalts ist nicht Zeichenfolge und Berufung Equals auf eine Referenz Gleichheit tut, und dies erklärt, warum Equals ( „Energie Attack“) versagt. Doch im zweiten Fall wird die Entscheidung, welche überlastete == statischen Betreiber sollte wird bei der Kompilierung aufgerufen werden und diese Entscheidung scheint zu == (string, string). dies legt nahe, mir, dass Inhalt eine implizite Konvertierung in einen String liefert.

Es gibt eine weitere Dimension zu einer früheren Antwort von @BlueMonkMN. Die zusätzliche Dimension ist, dass die Antwort auf die Titelfrage des @ Drahcir wie es auch auf angegeben wird, hängt wie wir am string Wert angekommen. Zur Veranschaulichung:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
string s5 = "te" + "st";
object s6 = s5;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));

Console.WriteLine("\n  Case1 - A method changes the value:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

Console.WriteLine("\n  Case2 - Having only literals allows to arrive at a literal:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s5), s1 == s5, s1.Equals(s5));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s6), s1 == s6, s1.Equals(s6));

Die Ausgabe lautet:

True True True

  Case1 - A method changes the value:
False True True
False False True

  Case2 - Having only literals allows to arrive at a literal:
True True True
True True True

Hinzufügen eines weiteren Punkt auf die Antwort.

.EqualsTo() Methode gibt Ihnen Bestimmung zum Vergleich gegen die Kultur und Groß- und Kleinschreibung.

Nur als Ergänzung zu den bereits guten Antworten: Dieses Verhalten auf Strings nicht darauf beschränkt ist oder unterschiedlichen numbertypes zu vergleichen. Auch wenn beiden Elemente vom Typ Objekt des gleichen zugrunde liegenden Typs. "==" wird nicht funktionieren.

Der folgende Screenshot zeigt die Ergebnisse der Vergleich zweier Objekt {int} - Werte

Der == Token in C # wird für zwei unterschiedliche Gleichheitsprüfung Operatoren verwendet. Wenn der Compiler, die Token trifft, wird sie prüfen, ob eine der beiden Arten verglichen, um einen Gleichheitsoperator Überlastung implementiert wurde entweder für die spezifische Kombination Typen verglichen wird (*) oder für eine Kombination von Typen zu denen beiden Typen umgewandelt werden. Wenn der Compiler eine solche Überlastung findet, wird es es verwenden. Andernfalls, wenn die beiden Typen beiden Referenztypen sind, und sie sind nicht unabhängig Klassen (entweder kann eine Schnittstelle sein, oder sie können verwandte Klassen), der Compiler betrachtet == als Referenz-Vergleichsoperator. Wenn keine der beiden Bedingungen zutreffen, wird Kompilierung fehlschlagen.

Hinweis

, dass einige andere Sprachen verwenden getrennte Token für die beiden Gleichheitsprüfung Operatoren. In VB.NET, zum Beispiel werden die = Token innerhalb von Ausdrücken ausschließlich für den überladbaren Gleichheitsprüfung Operator verwendet, und Is wird als Referenz-Test oder null-Test Operator verwendet. Ein = auf eine Art zu verwenden, die nicht die Gleichheit Prüfung Operator fehl enthebt, ebenso wie für andere Zwecke als die Prüfung Referenz Gleichheit oder Ungültigkeit zu verwenden Is versuchen.

(*) Art der Regel überlasten nur Gleichheit für den Vergleich mit sich selbst, aber es kann nützlich sein, für die Typen den Gleichheitsoperator für den Vergleich mit anderen bestimmten Typen zu überlasten; hat zum Beispiel könnte int (und meine Meinung nach sollte aber nicht) definiert mit float ein Gleichheitsoperator zum Vergleich, so dass 16.777.217 nicht selbst 16777216f gleich berichten würde. Wie es ist, da eine solche Operator definiert ist, wird C # die int zu fördern, um zu float, es Rundung auf 16777216f vor dem Gleichheitsprüfung Operator es sieht; dass Betreiber dann sieht zwei gleiche Gleitkommazahlen und meldet sie als gleich, keine Kenntnis von der Rundung stattfand.

Wirklich große Antworten und Beispiele!

Ich möchte nur den grundlegenden Unterschied zwischen den beiden addieren,

  

Operatoren wie == sind nicht polymorph, während Equals ist

Mit diesem Konzept im Kopf, wenn Sie irgendein Beispiel ausrechnen (von links Hand und die rechte Hand Referenztyp suchen, und die Überprüfung / zu wissen, ob der Typ tatsächlich Operator == überlastet und außer Kraft gesetzt Equals wird) Sie sind sicher zu bekommen die richtige Antwort.

Wenn wir erstellen ein beliebiges Objekt gibt es zwei Teile auf das Objekt ist der Inhalt und der andere Verweis auf diese Inhalte. == vergleicht Inhalt und Referenz; equals() vergleicht nur Inhalt

http: // www. codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq

==

kann der Operator == verwendet werden, um zwei Variablen jeglicher Art zu vergleichen, und vergleicht sie einfach die Bits .

int a = 3;
byte b = 3;
if (a == b) { // true }

. Hinweis: es gibt mehr Nullen auf der linken Seite des int aber wir nicht darauf, dass etwa hier

int a (00000011) == Byte b (00000011)

Denken Sie daran, Operator == nur über das Muster der Bits in den Variablen kümmert.

Verwenden == Wenn zwei Referenzen (Primitive) auf dem Heap auf das gleiche Objekt beziehen.

Die Regeln sind die gleichen, ob die Variable eine Referenz oder primitiv.

Foo a = new Foo();
Foo b = new Foo();
Foo c = a;

if (a == b) { // false }
if (a == c) { // true }
if (b == c) { // false }

a == c gilt a == b ist false

das Bitmuster ist für a und c, so dass sie gleich mit ==.

Equal ():

Mit dem equals () Methode, um zu sehen , wenn zwei verschiedene Objekte gleich sind .

Wie zwei verschiedene String-Objekte, die sowohl die Charaktere in „Jane“ repräsentieren

Der einzige Unterschied zwischen Equal und == ist auf Objekttyp Vergleich. in anderen Fällen, wie zum Beispiel Referenztypen und Werttypen, sie sind fast die gleiche (entweder beide sind bitweise Gleichheit oder beide Referenz Gleichheit).

Objekt: Equals: bitweise Gleichheit ==: Referenz Gleichheit

string: (entspricht und == sind die gleichen für Zeichenfolge, aber wenn man von String-Objekt geändert wird, dann wird Vergleichsergebnis unterschiedlich sein) Equals: bitweise Gleichheit ==: bitweise Gleichheit

Siehe hier für weitere Erklärung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top