简体   繁体   English

关于IEqualityComparer的问题 <T> /清单 <T> 。不同()

[英]Questions about IEqualityComparer<T> / List<T>.Distinct()

Here is the equality comparer I just wrote because I wanted a distinct set of items from a list containing entities. 这是我刚刚写的相等比较器,因为我想要一组包含实体的列表中的一组不同项目。

    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. Why does Distinct require a comparer as opposed to a Func<T,T,bool> ? 为什么Distinct要求比较器而不是Func<T,T,bool>
  2. Are (A) and (B) anything other than optimizations, and are there scenarios when they would not act the expected way, due to subtleness in comparing references? (A)和(B)除了优化之外是否还有其他功能?是否存在由于比较参考的细微之处而无法按预期方式运行的情况?
  3. If I wanted to, could I replace (C) with 如果我愿意,可以将(C)替换为

    return GetHashCode(x) == GetHashCode(y)

  1. So it can use hashcodes to be O(n) as opposed to O(n 2 ) 因此它可以使用哈希码为O(n)而不是O(n 2
  2. (A) is an optimization. (一)是一种优化。
    (B) is necessary; (B)是必需的; otherwise, it would throw an NullReferenceException . 否则,将抛出NullReferenceException If Invoice is a struct, however, they're both unnecessary and slower . 但是,如果Invoice是结构,则它们既不必要又
  3. No. Hashcodes are not unique 否。 哈希码不是唯一的
  • A is a simple and quick way to ensure that both objects located at the same memory address so both references the same object. A是确保两个对象都位于同一内存地址的简单且快速的方法,因此它们都引用同一对象。
  • B - if one of the references is null - obviuosly it does not make any sense doing equality comparision B如果引用之一为空-显然,进行相等比较没有任何意义
  • C - no, sometimes GetHashCode() can return the same value for different objects ( hash collision ) so you should do equality comparison C否,有时GetHashCode()可以为不同的对象返回相同的值( 哈希冲突 ),因此您应该进行相等比较

Regarding the same hash code value for different objects, MSDN : 关于不同对象的相同哈希码值, MSDN

If two objects compare as equal, the GetHashCode method for each object must return the same value. 如果两个对象比较相等,则每个对象的GetHashCode方法必须返回相同的值。 However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values. 但是,如果两个对象的比较不相等,则两个对象的GetHashCode方法不必返回不同的值。

Distinct() basically works on the term "not equal". Distinct()基本上适用于术语“不相等”。 therefore, if your list contains non-primitiv types, you must implement your own EqualityComparer. 因此,如果您的列表包含非基本类型,则必须实现自己的EqualityComparer。

At A, you check out whether the objects are identical or not. 在A处,检查对象是否相同。 If two objects are equal, they don't have to be identical, but if they are identical, you can be sure that they are equal. 如果两个对象相等,则它们不必相同,但是如果它们相同,则可以确保它们相等。 So the A part can increase the method's effectivity in some cases. 因此,在某些情况下,A部分可以提高方法的有效性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM