2010-11-06 4 views
7

aramadı üzerine yazılmış Eşittir. Ben her ikisi de eşit olup olmadığını doğrulamak için == operatörünü kullanıyorum ve bunların gerçekten eşit olduklarını doğrulamak için karma kodları aynı ise hem GetHashCode hem de Eşittir. C# GetHashCode/I GetHashCode ile ilgili bir sorun bakan ve bir sınıf için geçersiz hangi Eşittir ediyorum

Ama benim için sürpriz

denilen ve eşitlik testinin sonucu (aslında gerçek olması gerekirken) yanlıştır olsun de.

geçersiz kılma kodu:

public class User : ActiveRecordBase<User> 

     [...] 

     public override int GetHashCode() 
     { 
      return Id; 
     } 

     public override bool Equals(object obj) 
     { 
      User user = (User)obj; 
      if (user == null) 
      { 
       return false; 
      } 

      return user.Id == Id; 
     } 
    } 

Eşitlik kontrol:

if (x == y) // x and y are both of the same User class 
    // I'd expect this test to call both GetHashCode and Equals 
+4

'o nesne üzerinde' == 'operatörünü kullanır gibi' Equals' yöntemi çağırmak == 'aslında yoktu, o zaman bir yığın taşmasına neden olabilir ... – Guffa

+0

kodunda şey yok ederse Bu, GetHashCode() öğesini çağırmaya ihtiyaç duyduğunu gösterir. Bu sadece nesneyi bir koleksiyonun anahtarı olarak kullanırsanız denir. – RenniePet

cevap

11

Operatör ==.GetHashCode() veya .Equals() ya tamamen ayrıdır.

Microsoft'tan Guidelines for Overloading Equals() and Operator == ilginizi çekebilir.

kısa versiyonu: Kullanım .Equals()eşitlik karşılaştırmalar uygulamaktır. Eğer (her eşit örneği etkili bir şekilde aynı olduğu düşünülebilir) değişmez bir tür oluşturma durumunda kimlik karşılaştırmalar için operatör == kullanın veya. Ayrıca, .Equals() sanal bir yöntemdir ve alt sınıflar tarafından geçersiz kılınabilir, ancak operatör ==, kullanıldığı yerde ifadenin derleme zamanı türüne bağlıdır.

Son olarak, tutarlı olması için, .GetHashCode() sen .Equals() uygulamak her zaman uygulamak. Operatör =='u aşırı yüklediğinizde, aşırı yüklenme operatörü !=.

+0

Nesnelerim değişebilir. == işlecini çağırmanın aslında daha önce çalıştığımı gördüğüm Equals yöntemini çağırmasını bekledim, ama neden şimdi işe yaramadığını anlamıyorum ve daha önce de çalıştım ... – tomzx

+0

@tomzx: The = = = 'operatör bunu yapmak için aşırı yüklemediğiniz sürece' .Equals() 'yöntemini asla çağırmaz. –

+1

@Daniel Tavsiyeniz "==" yanlıştır. Microsoft sürekli olarak IDENTITY karşılaştırmasını isterseniz, "ReferenceEquals" kullanmanız gerektiğini söylüyor. Örneğin dizeleri düşünün. Aynı CONTENTS, ancak farklı ADDRESSES olan iki dize yapmak için dize oluşturucu kullanırsanız, o zaman "==", TRUE (eşitlik karşılaştırması) döndürecektir, ancak ReferenceEquals FALSE döndürecektir. "==" genellikle bir EQUALITY karşılaştırması olarak kabul edilir ve genellikle bir EQUALS'ın yaptığı bir şey yapmaz gibi uygulanır. – ToolmakerSteve

1

belki User sınıfında bir daha yöntemi ekleme.

public virtual bool Equals(User other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return other.Id == Id; 
    }