关于IEqualityComparer的问题<t> / List <t> .Distinct()</t> </t>

时间:2011-12-15 21:23:23

标签: c# iequalitycomparer

这是我刚刚写的等式比较器,因为我想要一个包含实体的列表中的一组不同的项目。

    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. 如果我想,我可以用

    代替(C)

    return GetHashCode(x) == GetHashCode(y)

3 个答案:

答案 0 :(得分:4)

  1. 因此它可以使用哈希码为O(n)而不是O(n 2
  2. (A)是优化 (B)是必要的;否则,它会抛出NullReferenceException。 但是,如果Invoice是一个结构,那么它们都是不必要的,并且更慢
  3. 否。 Hashcodes不是唯一的

答案 1 :(得分:1)

  • A是一种简单快捷的方法,可以确保两个对象都位于同一个内存地址,因此它们都引用同一个对象。
  • B - 如果其中一个引用为null - 显然,进行相等比较没有任何意义
  • C - 不,有时GetHashCode()可以为不同的对象(hash collision)返回相同的值,因此您应该进行相等比较

关于不同对象的相同哈希码值,MSDN

  

如果两个对象比较相等,则每个对象的GetHashCode方法   对象必须返回相同的值。但是,如果两个对象没有   比较相同,两个对象的GetHashCode方法不相同   必须返回不同的值。

答案 2 :(得分:0)

Distinct()基本上适用于“不相等”一词。因此,如果您的列表包含非原始类型,则必须实现自己的EqualityComparer。

在A处,检查对象是否相同。如果两个对象相等,则它们不必相同,但如果它们相同,则可以确定它们是相同的。所以A部分可以在某些情况下增加方法的有效性。