2011-12-15 40 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部分可以在某些情况下增加方法的有效性。