5

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

    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需要比较器而不是 a Func<T,T,bool>
  2. (A) 和 (B) 是不是优化以外的任何东西,是否存在由于比较参考的微妙性而无法按预期方式执行的情况?
  3. 如果我愿意,我可以将 (C) 替换为

    return GetHashCode(x) == GetHashCode(y)

4

3 回答 3

4
  1. 所以它可以使用哈希码为 O(n) 而不是 O(n 2 )
  2. (A) 是一种优化。
    (B) 是必要的;否则,它会抛出一个NullReferenceException. 但是,如果Invoice是一个结构,它们既不必要又
  3. ,哈希码不是唯一的
于 2011-12-15T21:25:24.443 回答
1
  • A 是一种简单快捷的方法,可以确保两个对象都位于相同的内存地址,因此它们都引用了相同的对象。
  • B- 如果其中一个引用为空 - 显然进行相等比较没有任何意义
  • C- 不,有时GetHashCode()可以为不同的对象返回相同的值(哈希冲突),所以你应该进行相等比较

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

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

于 2011-12-15T21:28:40.917 回答
0

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

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

于 2011-12-15T21:31:09.430 回答