2013-12-20 66 views
5

如果我有像一個對象:如何檢查對象是否等於同一個類的新對象?

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

而且我想要的行爲:

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

a == b; 

和一個== b返回true,我必須重寫的Object.Equals()方法?或者有沒有其他的方式來做到這一點,而不是重寫Equals方法?

編輯

我想比較的數據,因爲我想知道,如果我調用返回一個新的對象或大於新對象用不同的數據對象

回答

8

有幾種方法可以做到這一點。默認情況下,Equals()==檢查參考平等,意思是:

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

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

因此,對象不是比較的值相等,這意味着:

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

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

要爲它們的值可以覆蓋比較對象Equals()GetHashcode()方法,像這樣:

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(); 
} 

現在你會看到其他結果比較時:

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 

==運算符未被覆蓋,因此仍然進行參考比較。

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); 
} 

現在運行檢查結果如下:

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 

更多閱讀:

這可以通過重載它還有 !=操作來解決
+1

有關實現自定義GetHashCode實現的更好方法,請參閱http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode。另外,爲什麼不在比較null時使用ReferenceEquals並避免投射?名稱比較是否區分大小寫?我猜並不是因爲在名稱方面,案件通常不重要。 – tvanfosson

0
object.Equals(object2); 

一個外部方法你案例:

a.Equals(b); 
+1

這只是比較引用,而不是數據(可能是什麼OP希望,但是,他們沒有指定)。 – James

2

這一切都取決於你想比較一下,在默認情況下Equals將參照因此比較

a == b 

在你的例子中將永遠是false。不過,如果你不喜歡的東西

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

然後a == b會因爲無論ab使用相同參考true

我是否必須重寫Object.Equals()方法?

覆蓋EqualsGetHashCode是推薦的方法,但是(出於參數的緣故),這不是唯一的方法。例如,您可以覆蓋==運算符,並在那裏進行比較。但是,單獨沿着這條路線有限制。

大多數比較檢查,如果不是全部,將在內部使用Equals,這就是爲什麼它是首選方法。見Guidelines for Overloading Equals() and Operator ==

+0

我試圖避免覆蓋路線,但最終似乎是解決我的問題,謝謝。 –

0

假設測試是

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

你想重載==操作。因此,您應該首先覆蓋Equals。如果您覆蓋Equals,則應始終覆蓋GetHashCode。如果你重載==運營商還必須重載!=操作:

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 ; 
    } 
} 

現在這種比較,而不是唯一的參考值(id):

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

是。你想和Person的對象進行比較,你需要從Object類中覆蓋equals和hashcode方法,默認情況下引用check(==)是通過equals方法完成的。

假設兩個具有相同名稱和id的人員只能被視爲同等使用equals和hashcode方法中的這些屬性。

使用Java IDE提供的方式生成equals和hashcode更容易。你可以嘗試下面的代碼。

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; 
    } 

} 
相關問題