比较两个列表并忽略特定属性

Fre*_*ter 7 c# generics comparison list iequalitycomparer

我有两个员工名单,我想从中获得唯一的记录,但这有一个扭曲.每个列表中都有一个Employee类:

public class  Employee
{

// I want to completely ignore ID in the comparison
public int ID{ get; set; }
// I want to use FirstName and LastName in comparison
public string FirstName{ get; set; }
public string LastName{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我想要匹配的唯一属性是FirstName和LastName.我想在比较中完全忽略ID.allFulltimeEmployees列表中有3名员工,allParttimeEmployees列表中有3名员工.名单上的两个项目的名字和姓氏相匹配 - 莎莉琼斯和弗雷德杰克逊.列表中有一个项不匹配,因为FirstName是相同的,但LastName不同:

emp.id = null; // not populated or used in comparison
emp.FirstName = "Joe"; // same
emp.LastName = "Smith"; // different

allFulltimeEmployees.Add(emp);

emp.id = 3; // not used in comparison
emp.FirstName = "Joe"; // a match
emp.LastName = "Williams"; // not a match - different last name

allParttimeEmployees.Add(emp);
Run Code Online (Sandbox Code Playgroud)

所以我想在比较两个列表时忽略类中的ID属性.我想将乔·威廉姆斯标记为不匹配,因为两个名单中史密斯和威廉姆斯的姓氏不匹配.

// finalResult should only have Joe Williams in it 

var finalResult = allFulltimeEmployees.Except(allParttimeEmployees);
Run Code Online (Sandbox Code Playgroud)

我尝试过使用IEqualityComparer,但它不起作用,因为它在参数中使用单个Employee类而不是IEnumerable列表:

public class EmployeeEqualityComparer : IEqualityComparer<Employee>
    {
        public bool Equals(Employee x, Employee y)
        {
            if (x.FirstName == y.FirstName && x.LastName == y.LastName)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public int GetHashCode(Employee obj)
        {
            return obj.GetHashCode();
        }
    }
Run Code Online (Sandbox Code Playgroud)

如何成功完成我想要的操作并执行此操作?谢谢你的帮助!

Ant*_*ram 12

你使用IEqualityComparer它的想法很好,这是你的执行错误.值得注意的是,你的GetHashCode方法.

public int GetHashCode(Employee obj) 
{ 
    return obj.GetHashCode(); 
} 
Run Code Online (Sandbox Code Playgroud)

IEqualityComparer定义两者EqualsGetHashCode 因为两者都很重要.GetHashCode实现此接口时不要忽略!它在平等比较中起着关键作用.不,这并不表示两个项目是相等的,但它表明两个元素不相同.两个相等的元素必须返回相同的哈希码.如果他们不这样做,他们就不能被认为是平等的.如果他们这样做,那么他们可能是平等的,而平等功能只有继续探索Equals.

将实现委托给GetHashCode实际雇员对象的方法,您依赖于Employee类使用的实现.只有当该实现被覆盖时,它才对您有用,并且只有在使用您的关键字段时才有用.如果是,那么您很可能首先不需要定义自己的外部比较器!

构建一个GetHashCode影响关键字段的方法,然后设置.

public int GetHashCode(Employee obj)
{
     // null handling omitted for brevity, but you will want to
     // handle null values appropriately

     return obj.FirstName.GetHashCode() * 117 
          + obj.LastName.GetHashCode(); 
}
Run Code Online (Sandbox Code Playgroud)

一旦你有这个方法,然后在你的通话中使用比较器Except.

var comparer = new EmployeeEqualityComparer();
var results = allFulltimeEmployees.Except(allParttimeEmployees, comparer);
Run Code Online (Sandbox Code Playgroud)