1

我需要在 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"**

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

4

1 回答 1

4

问题是您的GetHashCode(Person p). 如MSDN中所述:

实现需要确保如果方法为两个对象Equals返回truexy,则方法返回的值 GetHashCode必须x等于返回的值y

在您的情况下,p.GetHashCode()可能会为内存中的每个返回不同的值p,即使它们具有相同的值Id- 也就是说,两个不同的实例Person可能具有相同Id但不同的哈希码 - 所以这不足以满足上述要求的正确实施GetHashCode(Person p)。相反,使用这样的东西:

public int GetHashCode(Person p) {
    return p.Id;
}
于 2015-03-03T13:34:26.373 回答