Skip to main content
 首页 » 编程设计

c#之IEqualityComparerT> 自定义实现和集合操作

2024年02月06日31lexus

我需要在 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() 可能会为内存中的每个 p 返回不同的值,即使它们具有相同的 Id——也就是说,Person 的两个不同实例可能具有相同的 Id 但哈希码不同——因此这不足以满足上述正确实现的要求GetHashCode(Person p)。相反,使用这样的东西:

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