IEqualityComparer<T> 自定义实现和设置操作

IEqualityComparer<T> custom implementation and set-operations

我需要在 linq 中执行简单的集合操作(​​例如 Union、Except 和 Intersect)

class Person {
        public int Id { get; set; }
        public string Name { get; set; }

        public Person() { }

        public Person(int id, string name) {
            Id = id; Name = name;
        }

    }

比较器实现:

class PersonComparer : IEqualityComparer<Person> {
        public bool Equals(Person x, Person y) {
            return x.Id == y.Id;
        }

        public int GetHashCode(Person p) {
            return p.GetHashCode();
        }
    }

正在填充列表:

var list1 = new List<Person>();
        list1.Add(new Person(1, "John"));
        list1.Add(new Person(2, "Peter"));
        list1.Add(new Person(3, "Mike"));

        var list2 = new List<Person>();
        list2.Add(new Person(2, "Peter"));
        list2.Add(new Person(3, "Mike"));
        list2.Add(new Person(4, "Fred"));

    var comparer = new PersonComparer();

    var list3 = list1.Intersect(list2, comparer).ToList(); // **Empty List**
    var list4 = list1.Except(list2, comparer).ToList(); // **"John", "Peter", "Mike"**

看来我的比较器不起作用。为什么?

问题是您对 GetHashCode(Person p) 的实施。如 MSDN 中所述:

Implementations are required to ensure that if the Equals method returns true for two objects x and y, then the value returned by the GetHashCode method for x must equal the value returned for y.

在您的情况下,p.GetHashCode() 可能 return 内存中每个 p 的不同值,即使它们具有相同的 Id — 即两个不同的值Person 的实例可能具有相同的 Id 但哈希码不同——因此这不足以满足上述正确实现 GetHashCode(Person p) 的要求。相反,使用这样的东西:

public int GetHashCode(Person p) {
    return p.Id;
}