2009-04-21 42 views
37

Was ist der Unterschied zwischen und a == b für Werttypen, Referenztypen und Strings? Es scheint, als ob a == b für Strings gut funktioniert, aber ich versuche, sicher zu sein, gute Codierpraktiken zu verwenden.Was ist der Unterschied zwischen .Equals und ==

+0

Schauen Sie sich http://StackOverflow.com/Questions/144530/Die-Equals –

Antwort

34

Von When should I use Equals and when should I use ==:

Die Methode Equals ist nur ein virtuelles ein in System.Object definiert und außer Kraft gesetzt durch Unabhängig davon, welche Klassen wählen dies zu tun. Der Operator == ist ein Operator , der von Klassen überlastet werden kann, aber normalerweise Identitätsverhalten hat.

Für Referenztypen, bei denen == nicht überlastet wurde, vergleicht sie, ob zwei Referenzen auf dasselbe Objekt beziehen - das ist genau das, was die Implementierung von Equals tut in System.Object.

Werttypen bieten keine Überladung für == standardmäßig. Die meisten der Werttypen, die vom Framework bereitgestellt werden, stellen jedoch ihre eigene Überlast bereit. Die Standardimplementierung von Equals für einen Werttyp wird durch Valuetype zur Verfügung gestellt und verwendet Reflektion den Vergleich zu machen, was es macht deutlich langsamer als eine typspezifische Implementierung normalerweise wäre. Diese Implementierung auch Anrufe entspricht Paaren von Referenzen innerhalb der beiden Werte verglichen wird.

using System; 

public class Test 
{ 
    static void Main() 
    { 
     // Create two equal but distinct strings 
     string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); 
     string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); 

     Console.WriteLine (a==b); 
     Console.WriteLine (a.Equals(b)); 

     // Now let's see what happens with the same tests but 
     // with variables of type object 
     object c = a; 
     object d = b; 

     Console.WriteLine (c==d); 
     Console.WriteLine (c.Equals(d)); 
    } 
} 

Das Ergebnis dieses Programms kurzen Probe

True 
True 
False 
True 
0

"==" ist ein Operator, der je nach den zu vergleichenden Typen überladen werden kann, um verschiedene Dinge auszuführen.

Die Standardoperation von "==" ausgeführt ist a.Equals(b);

Hier ist, wie Sie diesen Operator für String-Typen überlasten könnten:

verschiedene
public static bool operator == (string str1, string str2) 
{ 
    return (str1.Length == str2.Length;) 
} 

Hinweis, dass dies kann

Abgeleitete Klassen als str1.Equals(str2); überschreiben und neu definieren Equals().

Soweit "Best Practices" gehen, hängt es von Ihrer Absicht ab.

+0

Könnten Sie klären, was Sie mit "Die Standardoperation von durchgeführt" == "ist a.Equals (b)". –

+0

Wenn Sie den Operator '==' nicht überladen, wird die gleiche Funktion wie mit der Funktion Equals() ausgeführt. Bei Strings wird ein Stringvergleich durchgeführt, bei Benutzertypen werden Referenzen verglichen. –

7

Auf einer einfachen Ebene ist der Unterschied, welche Methode aufgerufen wird. Die Methode == versucht, an Operator == zu binden, wenn sie für die betreffenden Typen definiert ist. Wenn für Werttypen no == gefunden wird, wird ein Wertevergleich durchgeführt und für Referenztypen wird ein Referenzvergleich durchgeführt. Ein .Equals-Aufruf führt einen virtuellen Versand der .Equals-Methode durch.

Was die einzelnen Methoden tun, ist alles im Code. Benutzer können diese Methoden definieren/überschreiben und alles tun, was sie wollen. Idealerweise sollten diese Methoden äquivalent sein (Entschuldigung für das Wortspiel) und die gleiche Ausgabe haben, aber es ist nicht immer der Fall.

+0

+1 Gut zu erwähnen, dass Equals eine virtuelle Methode ist. –

7

Ein signifikanter Unterschied zwischen ihnen ist, dass == eine statische Binäroperators ist, die auf zwei Instanzen eines Typs arbeitet während Equals eine Instanz Methode. Der Grund, warum dies wichtig ist, dass Sie dies tun können:

Foo foo = new Foo() 
Foo foo2 = null; 
foo2 == foo; 

Aber man kann dies nicht tun, ohne einen NullReferenceException zu werfen:

Foo foo = new Foo() 
Foo foo2 = null; 
foo2.Equals(foo); 
0

Für Strings Sie vorsichtig kulturspezifische Vergleiche sein wollen. Das klassische Beispiel ist das deutsche Doppel-S, das ein bisschen wie ein b aussieht. Dies sollte mit "ss" übereinstimmen, aber nicht in einem einfachen == Vergleich.

Für String-Vergleiche, die kultursensitiv sind: String.Compare (expected, value, StringComparison ....) == 0? mit der StringComparison-Überladung benötigen Sie.

0

standardmäßig sowohl == und .Equals() gleichwertig sind abgesehen von der Möglichkeit .Equals() auf einer null Instanz anrufen (die Sie würde ein NullReferenceException geben). Sie können jedoch die Funktionalität von beiden unabhängig voneinander außer Kraft setzen (obwohl ich mir nicht sicher bin, ob das jemals eine gute Idee wäre, wenn Sie versuchen, die Mängel eines anderen Systems zu umgehen), was bedeutet, dass Sie sie anders machen könnten .

Sie finden auf beiden Seiten des Gangs Personen, die zu benutzen sind. Ich bevorzuge den Operator und nicht die Funktion.

Wenn Sie jedoch über Strings sprechen, ist es wahrscheinlich eine bessere Idee, string.Compare() anstelle von einer dieser Optionen zu verwenden.

3

Eine einfache Möglichkeit, sich an den Unterschied zu erinnern, ist, dass a.Equals(b) eher
a == (object)b ist. Die Methode ist nicht generisch und akzeptiert ein Argument vom Typ "object". Wenn Sie also mit dem Operator == vergleichen, müssen Sie so darüber nachdenken, als ob der rechte Operand zuerst zum Objekt umgewandelt würde.

Eine Folge ist, dass a.Equals(b) wird fast immer einen Wert zurück, für a und b, unabhängig vom Typ (die normale Art und Weise zu überlasten ist nur false zurück, wenn b ein unbekannter Typ ist). a == b wird nur eine Ausnahme auslösen, wenn für diese Typen kein Vergleich verfügbar ist.

6

In den meisten Stenografie Antwort:

== opertator ist Identität zu überprüfen. (d. H.: A == b sind diese beiden das gleiche Objekt?)

.Equals() soll den Wert prüfen. (dh: a.Equals (b) halten beide identische Werte?)

Mit einer Ausnahme:
Für Zeichenfolge und vordefinierten Wertetypen (wie int, float etc ..),
der Operator == wird für Wert und nicht für Identität antworten. (wie mit .Equals())

Verwandte Themen