我需要在 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
Equalsmethod returns true for two objectsxandy, then the value returned by theGetHashCodemethod forxmust equal the value returned fory.
在您的情况下,p.GetHashCode() 可能会为内存中的每个 p 返回不同的值,即使它们具有相同的 Id——也就是说,Person 的两个不同实例可能具有相同的 Id 但哈希码不同——因此这不足以满足上述正确实现的要求GetHashCode(Person p)。相反,使用这样的东西:
public int GetHashCode(Person p) {
return p.Id;
}
