it-swarm.com.de

== oder .Equals ()

Warum eins über dem anderen verwenden?

56
Dan

== ist der Identitätstest. Es wird true zurückgegeben, wenn die beiden getesteten Objekte tatsächlich das gleiche Objekt sind. Equals() führt einen Gleichheitstest durch und gibt true zurück, wenn die beiden Objekte sich selbst als gleichwertig betrachten.

Identitätsprüfungen sind schneller, sodass Sie sie verwenden können, wenn keine kostspieligeren Gleichheitstests erforderlich sind. Vergleich mit null oder der leeren Zeichenfolge.

Es ist möglich, eine dieser beiden Methoden zu überladen, um ein anderes Verhalten bereitzustellen (z. B. Identitätsprüfungen für Equals()). Wenn Sie jedoch Ihren Code lesen, tun Sie dies bitte nicht.


Unten aufgeführt: Einige Typen wie String oder DateTime stellen Überladungen für den ==-Operator bereit, die ihm Gleichheitssemantik verleihen. Das genaue Verhalten hängt also von den Objekttypen ab, die Sie vergleichen.


Siehe auch:

56
John Millikin

@ John Millikin:

Nachfolgend wird darauf hingewiesen: Einige Werttypen wie DateTime stellen Überladungen für den Operator == bereit, die Gleichheitssemantik bewirken. Das genaue Verhalten hängt also von den Typen der> Objekte ab, die Sie vergleichen.

Zu erarbeiten:

DateTime ist als Struktur implementiert. Alle Strukturen sind untergeordnete Elemente von System.ValueType.

Da die Kinder von System.ValueType auf dem Stapel leben, gibt es keinen Verweiszeiger auf den Heap und daher keine Möglichkeit, eine Verweisprüfung durchzuführen. Sie müssen Objekte nur nach Wert vergleichen.

System.ValueType überschreibt .Equals () und ==. Um eine reflexionsbasierte Gleichheitsprüfung zu verwenden, verwendet Reflection den jeweiligen Feldwert.

Da die Reflektion etwas langsam ist, müssen Sie .Equals () überschreiben und Ihren eigenen Wertüberprüfungscode hinzufügen, wenn Sie Ihre eigene Struktur implementieren. Dies ist jedoch viel schneller. Rufen Sie nicht einfach base.Equals ();

20
FlySwat

Alle anderen haben dich ziemlich abgedeckt, aber ich habe noch ein Wort. Hin und wieder wird jemandem, der auf sein Leben (und den seiner Angehörigen) schwört, dass .Equals effizienter/besser/bewährter ist oder eine andere dogmatische Linie. Ich kann nicht mit Effizienz sprechen (gut, OK, unter bestimmten Umständen kann ich), aber ich kann mit einem großen Problem sprechen, das auftauchen wird: .Equals erfordert, dass ein Objekt existiert. (Hört sich dumm an, wirft aber Leute ab.)

Sie können Folgendes nicht tun:

StringBuilder sb = null;
if (sb.Equals(null))
{
    // whatever
}

Für mich und vielleicht für die meisten Leute scheint es offensichtlich, dass Sie eine NullReferenceException erhalten. Befürworter von .Equals vergessen jedoch diesen kleinen Faktoid. Einige werden sogar "geworfen" (sorry, konnte nicht widerstehen), wenn sie sehen, dass die NullRefs auftauchen.

(Und Jahre vor dem DailyWTF - Posting habe ich tatsächlich mit jemandem zusammengearbeitet, der mandated dass alle Gleichheitsprüfungen .Equals anstelle von == sind. Selbst der Beweis seiner Ungenauigkeit half nicht alle seine anderen Regeln zu brechen, so dass kein Verweis von einer Methode oder Eigenschaft zurückgegeben wurde, und es hat am Ende geklappt.)

15
John Rudy

== ist im Allgemeinen das "Identität" gleichbedeutend "Objekt a ist tatsächlich das gleiche Objekt im Speicher wie Objekt b". 

equals () bedeutet, dass die Objekte logisch gleich sind (z. B. aus betriebswirtschaftlicher Sicht). Wenn Sie also Instanzen einer benutzerdefinierten Klasse vergleichen, müssen Sie im Allgemeinen equals () verwenden und definieren, wenn Dinge wie eine Hashtable ordnungsgemäß funktionieren sollen. 

Wenn Sie die sprichwörtliche Person-Klasse mit den Eigenschaften "Name" und "Address" hätten und Sie diese Person als Schlüssel in einer Hashtable mit weiteren Informationen dazu verwenden möchten, müssen Sie equals () (und hash) implementieren, damit Sie dies tun können könnte eine Instanz einer Person erstellen und sie als Schlüssel in der Hashtabelle verwenden, um die Informationen abzurufen.

Allein mit == würde Ihre neue Instanz nicht dieselbe sein. 

6
Joshua DeWald

Sowohl Equals als auch == können überlastet sein, so dass die genauen Ergebnisse beim Aufrufen des einen oder des anderen variieren. Beachten Sie, dass == zur Kompilierzeit bestimmt wird. Während die tatsächliche Implementierung geändert werden kann, wird jedoch festgelegt, welcher == zur Kompilierzeit verwendet wird. Im Gegensatz zu Equals kann dies aufgrund des Laufzeittyps der linken Seite eine andere Implementierung verwenden.

Zum Beispiel führt string einen Gleichheitstest für == durch.

Beachten Sie auch, dass die Semantik von beiden komplex sein kann.

Die beste Vorgehensweise ist, Gleichheit wie in diesem Beispiel zu implementieren. Beachten Sie, dass Sie dies alles vereinfachen oder ausschließen können, je nachdem, wie Sie Ihre Klasse verwenden möchten, und dass structs bereits das meiste davon erhalten.

class ClassName
{
    public bool Equals(ClassName other)
    {
        if (other == null)
        {
            return false;
        }
        else
        {
            //Do your equality test here.
        }
    }

    public override bool Equals(object obj)
    {
        ClassName other = obj as null; //Null and non-ClassName objects will both become null
        if (obj == null)
        {
            return false;
        }
        else
        {
            return Equals(other);
        }
    }

    public bool operator ==(ClassName left, ClassName right)
    {
        if (left == null)
        {
            return right == null;
        }
        else
        {
            return left.Equals(right);
        }
    }

    public bool operator !=(ClassName left, ClassName right)
    {
        if (left == null)
        {
            return right != null;
        }
        else
        {
            return !left.Equals(right);
        }
    }

    public override int GetHashCode()
    {
        //Return something useful here, typically all members shifted or XORed together works
    }
}
3
Guvante

Nach MSDN :

In C # gibt es zwei verschiedene Arten von Gleichheit: Referenzgleichheit (auch als Identität bezeichnet) und Wertgleichheit. Wertgleichheit ist die allgemein verstandene Bedeutung von Gleichheit: Dies bedeutet, dass zwei Objekte die gleichen Werte enthalten. Zum Beispiel haben zwei Ganzzahlen mit dem Wert 2 die Wertgleichheit. Referenzgleichheit bedeutet, dass nicht zwei Objekte verglichen werden müssen. Stattdessen gibt es zwei Objektreferenzen, und beide beziehen sich auf dasselbe Objekt.

...

Standardmäßig prüft der Operator == auf Referenzgleichheit, indem er bestimmt, ob zwei Referenzen dasselbe Objekt angeben.

2
Jason Olson

Das Beispiel ist, weil die Klasse DateTime die IEquatable-Schnittstelle implementiert, die eine "typspezifische Methode zum Bestimmen der Gleichheit von Instanzen" implementiert. nach MSDN .

2
Peter K.

Zu beachten ist noch Folgendes: Der Operator == ist möglicherweise nicht aufrufbar oder hat eine andere Bedeutung, wenn Sie auf das Objekt aus einer anderen Sprache zugreifen. In der Regel ist es besser, eine Alternative zu haben, die nach Namen aufgerufen werden kann.

2
Jason Baker

Ich habe Object.ReferenceEquals () gesehen, das in Fällen verwendet wird, in denen man wissen möchte, ob zwei Referenzen auf dasselbe Objekt verweisen

1
GregUzelac

verwenden Sie equals, wenn Sie den Inhalt der verglichenen Objekte als gleich angeben möchten. Verwenden Sie == für Grundwerte oder wenn Sie prüfen möchten, ob die zu vergleichenden Objekte ein und dasselbe Objekt sind. Bei Objekten prüft ==, ob der Adresszeiger der Objekte gleich ist.

1
Jasper

In den meisten Fällen sind sie gleich, daher sollten Sie zur Klarheit == verwenden. Gemäß den Microsoft Framework Design Guidelines:

"DOStellen Sie sicher, dass Object.Equals und die Gleichheitsoperatoren exakt die gleiche Semantik und ähnliche Leistungsmerkmale aufweisen." https://docs.Microsoft.com/en-us/dotnet/standard/design-Richtlinien/Gleichheitsoperatoren

Manchmal überschreibt jemand Object.Equals, ohne Gleichheitsoperatoren anzugeben. In diesem Fall sollten Sie Equals zum Testen der Wertegleichheit und Object.ReferenceEquals zum Testen der Referenzgleichheit verwenden.

1
Dave Mackersie

Wenn Sie das Objekt (beispielsweise durch dotPeek) zerlegen, so 

public virtual bool Equals(Object obj)

beschrieben als:

// Returns a boolean indicating if the passed in object obj is
// Equal to this.  Equality is defined as object equality for reference
// types and bitwise equality for value types using a loader trick to
// replace Equals with EqualsValue for value types). 
//

Also hängt vom Typ ab. Zum Beispiel:

        Object o1 = "vvv";
        Object o2 = "vvv";
        bool b = o1.Equals(o2);

        o1 = 555;
        o2 = 555;
        b = o1.Equals(o2);

        o1 = new List<int> { 1, 2, 3 };
        o2 = new List<int> { 1, 2, 3 };
        b = o1.Equals(o2);

Das erste Mal, wenn b wahr ist (bei Werttypen gleich ausgeführt), ist das zweite Mal, wenn b wahr ist (gleich für Wertetypen ausgeführt), das dritte Mal, wenn b falsch ist (gleich für Referenztypen).

0
zzfima