2013-12-20 9 views
5

Wenn ich ein Objekt wie:Wie überprüfe ich, ob ein Objekt gleich einem neuen Objekt derselben Klasse ist?

public class Person 
{ 
    public int id {get;set;} 
    public string name {get;set;} 
} 

Und ich möchte das Verhalten:

Person a = new Person(); 
Person b = new Person(); 

a == b; 

und dass a == b true zurückgibt, muss ich die Object.Equals außer Kraft setzen() -Methode ? Oder gibt es eine andere Möglichkeit, die Equals-Methode zu überschreiben?

EDIT

Ich mag Daten vergleichen, da ich, wenn eine externe Methode wissen will, dass ich zurückkehrt, ein neues Objekt oder ein Objekt mit unterschiedlichen Daten als ein neues Objekt in

Antwort

8

Es gibt ein paar Möglichkeiten, wie Sie dies tun können. Standardmäßig Equals() und == Prüfung für Referenz Gleichheit, das heißt:

Person a = new Person(); 
Person b = a: 

a.Equals(b); //true 
a == b; //true 

Und deshalb werden die Objekte für Wertgleichheit nicht verglichen, das heißt:

Person a = new Person { id = 1, name = "person1" }; 
Person b = new Person { id = 1, name = "person1" }; 

a.Equals(b); //false 
a == b; //false 

Um Objekte für ihre Werte vergleichen Sie die überschreiben können Equals() und GetHashcode() Methoden, wie folgt aus:

public override bool Equals(System.Object obj) 
{ 
    if (obj == null) 
     return false; 

    Person p = obj as Person; 
    if ((System.Object)p == null) 
     return false; 

    return (id == p.id) && (name == p.name); 
} 

public bool Equals(Person p) 
{ 
    if ((object)p == null) 
     return false; 

    return (id == p.id) && (name == p.name); 
} 

public override int GetHashCode() 
{ 
    return id.GetHashCode()^name.GetHashCode(); 
} 

Jetzt werden Sie andere Ergebnisse sehen bei einem Vergleich:

Person a = new Person { id = 1, name = "person1" }; 
Person b = new Person { id = 1, name = "person1" }; 
Person c = a; 

a == b; //false 
a == c; //true 
a.Equals(b); //true 
a.Equals(c); //true 

Der == Betreiber nicht außer Kraft gesetzt wird und daher immer noch tut Referenz Vergleich.

public static bool operator ==(Person a, Person b) 
{ 
    if (System.Object.ReferenceEquals(a, b)) 
     return true; 

    if ((object)a == null || (object)b == null) 
     return false; 

    return a.id == b.id && a.name == b.name; 
} 

public static bool operator !=(Person a, Person b) 
{ 
    return !(a == b); 
} 

nun die Kontrollen laufen ergibt folgende: Dies kann durch Überlastung als auch die != Operator gelöst werden

Person a = new Person { id = 1, name = "person1" }; 
Person b = new Person { id = 1, name = "person1" }; 
Person c = a; 

a == b; //true 
a == c; //true 
a.Equals(b); //true 
a.Equals(c); //true 

More reading:

+1

Weitere Informationen zum Implementieren einer benutzerdefinierten GetHashCode-Implementierung finden Sie unter http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode. Warum nicht ReferenceEquals beim Vergleich mit null verwenden und die Besetzung vermeiden? Und sollte der Name Vergleich Groß-und Kleinschreibung beachten? Ich rate nicht, weil der Fall normalerweise nicht wichtig ist, wenn es um Namen geht. – tvanfosson

0
object.Equals(object2); 

rufe Sie Ihre Fall:

a.Equals(b); 
+1

Dies vergleicht nur Referenzen, keine Daten (das kann was sein das OP möchte jedoch nicht angegeben haben). – James

2

Das hängt alles davon ab, was Sie versuchen standardmäßig zu vergleichen, Equals durch Bezugnahme vergleichen wird daher

a == b 

in Ihrem Beispiel wird immer false sein. Wenn Sie jedoch etwas tun, wie

Person a = new Person(); 
Person b = a; 

Dann würde a == btrue sein sowohl weil a und b sind die gleiche Referenz verwenden.

Muss ich die Methode Object.Equals() überschreiben?

Aufschalten Equals und GetHashCode ist die empfohlene Vorgehensweise, jedoch (für Argumente willen), es ist nicht der einzige Weg. Sie könnten zum Beispiel den Operator == überschreiben und dort Ihren Vergleich durchführen. Es gibt jedoch Einschränkungen beim alleinigen Weggehen.

Die meisten Vergleichsprüfungen, wenn nicht alle, verwenden Equals intern, weshalb es der bevorzugte Ansatz ist. Siehe Guidelines for Overloading Equals() and Operator ==.

+0

Ich habe versucht, die Override-Route zu vermeiden, aber am Ende scheint es, dass die Lösung für mein Problem ist, danke. –

0

Angenommen-Test ist Klasse

Test a = new Test() { Num = 1, Str = "Hi" }; 
Test b = new Test() { Num = 1, Str = "Hi" }; 
bool areEqual = System.Object.ReferenceEquals(a, b); 
2

Sie den == Betreiber zu überlasten möchten. Daher sollten Sie zuerst Equals überschreiben. Wenn Sie Equals überschreiben, sollten Sie immer auch GetHashCode überschreiben. Wenn Sie die == Betreiber Überlastung müssen Sie auch Überlastung den != Betreibers:

public class Person 
{ 
    public int id {get;set;} 
    public string name {get;set;} 

    public override bool Equals(object obj) 
    { 
     Person p2 = obj as Person; 
     if (object.ReferenceEquals(null, p2)) return false; 
     return id == p2.id; 
    } 

    public static bool operator ==(Person p1, Person p2) 
    { 
     if (object.ReferenceEquals(null, p1)) 
      return object.ReferenceEquals(null, p2); 
     else if (object.ReferenceEquals(null, p2)) 
      return false; 
     return p1.Equals(p2); 
    } 

    public static bool operator !=(Person p1, Person p2) 
    { 
     if (object.ReferenceEquals(null, p1)) 
      return !object.ReferenceEquals(null, p2); 
     else if (object.ReferenceEquals(null, p2)) 
      return true; 
     return !p1.Equals(p2); 
    } 

    public override int GetHashCode() 
    { 
     return id ; 
    } 
} 

Nun ist dieser Wert vergleichen (die id) statt nur Referenzen:

Person p1 = new Person { id = 1, name = "Jeff" }; 
Person p2 = new Person { id = 2, name = "Tim" }; 
bool equalPersons = p1 == p2; // false 
Person p3 = new Person { id = 1, name = "Jeff 2.0" }; // same id -> equal 
equalPersons = p1 == p3; // true 

MSDN: Guidelines for Overloading Equals() and Operator ==

0

Ja.Wenn Sie Objekte von Person vergleichen möchten, müssen Sie die Methoden equals und hashcode aus der Object-Klasse überschreiben, da standardmäßig die Referenzprüfung (==) über die equals-Methode erfolgt.

Angenommen, zwei Personen mit demselben Namen und derselben ID können nur als gleichwertig betrachtet werden, verwenden Sie diese beiden Eigenschaften in equals und in der hashcode-Methode.

Die Generierung von equals und hashcode ist mit den bereitgestellten Java-IDEs einfacher. U kann unter dem Code versuchen.

public class Person { 

    private int id; 
    private String name; 

    // id getters and setters 

    // name getters and setters 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + id; 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Person other = (Person) obj; 
     if (id != other.id) 
      return false; 
     if (name == null) { 
      if (other.name != null) 
       return false; 
     } else if (!name.equals(other.name)) 
      return false; 
     return true; 
    } 

}