2011-12-15 68 views
5

這是我剛纔寫的等號比較器,因爲我想從包含實體的列表中選擇一組不同的項目。關於IEqualityComparer的問題<T> /列表<T> .Distinct()

class InvoiceComparer : IEqualityComparer<Invoice> 
    { 
     public bool Equals(Invoice x, Invoice y) 
     { 
      // A 
      if (Object.ReferenceEquals(x, y)) return true; 

      // B 
      if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; 

      // C 
      return x.TxnID == y.TxnID; 
     } 

     public int GetHashCode(Invoice obj) 
     { 
      if (Object.ReferenceEquals(obj, null)) return 0; 
      return obj.TxnID2.GetHashCode(); 
     } 
    } 
  1. 爲什麼Distinct需要一個比較器,而不是一個Func<T,T,bool>
  2. (A)和(B)除了優化之外是否還有其他內容,並且由於比較引用的細微程度,他們是否會以不可預期的方式行事?
  3. 如果我想,我能與

    return GetHashCode(x) == GetHashCode(y)

+0

隨機self-agrandizing觀察:這可能會使一個很好的考試queuing – 2011-12-15 22:03:13

回答

4
  1. 代替(C),所以它可以使用哈希碼是爲O(n),而不是爲O(n )
  2. (A)是一種優化。 (B)
    (B)否則,它會拋出一個NullReferenceException。 如果Invoice是一個結構,但是,它們都是不必要的,並且較慢
  3. 號散列碼不是唯一
+0

我的大腦不工作:我想我在文檔中讀到「相等的對象返回相同的哈希碼」... – 2011-12-15 21:29:54

1
  • A是一種簡單,快捷的方式,以確保位於相同的內存地址,從而既引用同一對象兩個對象。
  • B - 如果其中一個引用爲空 - obviuosly它沒有任何意義做平等對比
  • C - 沒有,有時GetHashCode()可以返回不同的對象相同的值(hash collision),所以你應該做相等比較

關於用於不同的對象相同的散列碼值,MSDN

如果兩個對象的比較結果爲相等,對於每個01 GetHashCode方法對象必須返回相同的值。但是,如果兩個對象 的比較結果不相等,則兩個對象的GetHashCode方法不需要 必須返回不同的值。

0

Distinct()基本上適用於術語「不等於」。因此,如果您的列表包含非原始類型,則必須實現您自己的EqualityComparer。

在A處,檢查對象是否相同。如果兩個對象相同,則它們不必相同,但如果它們相同,則可以確定它們是平等的。所以A部分可以在某些情況下增加方法的有效性。