2008-12-04 99 views
1

我有一個Customer類。繼承相等比較器

public class Customer 
{ 
    private string _id; 
    private string _name; 
    // some more properties follow 

我繼承了EqualityComparer表單MyEqualityComparer(Customer)。
這我打算在LINQ查詢中使用。
MyEqualityComparer用於在兩個對象之間進行部分檢查。
如果customer.id和customer.name匹配,我將對象視爲相等。

public class MyComparer : System.Collections.Generic.EqualityComparer<Customer> 
{ 
    public override bool Equals(Customer x, Customer y) 
    { 
     if (x.Id == y.Id && x.Name == y.Name) 
      return true; 
     else 
      return false; 
    } 

    public override int GetHashCode(Customer obj) 
    { 
     return string.Concat(obj.Id,obj.Name).GetHashCode(); 
    } 

} 

我提到generating hashcode
我很不確定如何連接字符串並將其用作散列碼。
這是安全的,我正在嘗試做什麼?

回答

5

一個相當簡單的方法基於多個字段返回一個哈希碼見this question on hashcodes。這樣說,我不會從EqualityComparer<T>我自己得到 - 我只是直接實現了IEqualityComparer<T>。我不確定EqualityComparer<T>真的會給你帶來什麼價值,除了實施非通用IEqualityComparer

一對夫婦更多的事情:

  • 中值爲
  • 您現在的Equals代碼可以簡化爲您應該處理無效:

    return x.Id == y.Id && x.Name == y.Name; 
    

更全面執行的Equals的可能成爲:

public override bool Equals(Customer x, Customer y) 
{ 
    if (object.ReferenceEquals(x, y)) 
    { 
     return true; 
    } 
    if (x == null || y == null) 
    { 
     return false; 
    } 
    return x.Id == y.Id && x.Name == y.Name; 
} 
+0

小錯誤 - 在與null比較之前,您需要將x和y轉換爲對象。請參閱http://msdn.microsoft.com/en-us/library/ms173147 – Thracx 2012-11-24 23:32:08

3

你應該從可能的「碰撞」的角度來看它,例如,當兩個不同的對象獲得相同的散列碼時。對於「1,2any」和「12,any」這樣的對,情況可能如此,對中的值是「id」和「name」。如果您的數據無法做到這一點,那麼您很好。否則,你可以把它改成這樣的:

return obj.Id.GetHashCode()^obj.Name.GetHashCode(); 
+0

不要忘記檢查ID和名稱 – 2008-12-04 13:13:19

+0

不幸的是,在很多情況下使用XOR會產生衝突。請參閱http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-systemobjectgethashcode#263416。在名稱/ ID的情況下可能沒問題,但總的來說這不是一個好主意。 – 2008-12-04 14:07:41

1

ReSharper的(從JetBrains的夢幻般的重構插件)認爲它應該是:

public override int GetHashCode(Customer obj) 
{ 
    unchecked 
    { 
     return ((obj.Id != null ? obj.Id.GetHashCode() : 0) * 397) 
      ^(obj.Name != null ? obj.Name.GetHashCode() : 0); 
    } 
} 

我不得不承認,我幾乎總是隻讓ReSharper的生成平等和哈希代碼實現了我。我已經測試了他們的實現,並發現它與我手寫的任何東西都不差。所以我通常會採用我不需要輸入的實現。