C# IEnumerable.Except()不排除
我有两个数组。第一个包含所有成员,第二个包含所有声称的成员。我试图使用except只获取无人认领的成员,但结果数组包含所有成员(第一个数组的精确副本) 我还尝试使用where查询获取无人认领的成员,结果相同C# IEnumerable.Except()不排除,c#,linq,C#,Linq,我有两个数组。第一个包含所有成员,第二个包含所有声称的成员。我试图使用except只获取无人认领的成员,但结果数组包含所有成员(第一个数组的精确副本) 我还尝试使用where查询获取无人认领的成员,结果相同 var junior_handler_Unclaimed = junior_handler_All.Where(i => !junior_handler_Claimed.Contains(i.Junior_Handler_ID.ToString())); 你知道为什么这两个元素都不起
var junior_handler_Unclaimed = junior_handler_All.Where(i => !junior_handler_Claimed.Contains(i.Junior_Handler_ID.ToString()));
你知道为什么这两个元素都不起作用了吗?比较元素的方法是调用
GetHashCode()
,如果散列相等,则调用Equals
,检查两个元素是否相等
因此,如果将此应用于没有自己的GetHashCode()
和Equals()
实现的引用类型,则此比较将导致一个简单的引用等式检查
您可能不想比较对象的引用,但需要某种ID。因此,您有两个选项:
您可以在类中重写GetHashCode()
和Equals()
:
public class Person
{
public int ID { get; set; }
public override bool Equals(object o)
{
return ID == (o as Person)?.ID;
}
public override int GetHashCode()
{
return ID;
}
}
或者实现一个IEqualityComparer
,如下所示:
public class Comparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.ID == y.ID; // or whatever defines your equality
}
public int GetHashCode(Person obj)
{
return obj.ID; // or whatever makes a good hash
}
}
您需要更新类以实现IEquatable和/或重写Equals和GetHashCode 参考资料: 除以下情况外: 通过使用默认相等比较器来比较值,生成两个序列的集差 在默认相等比较器上: 默认属性检查类型T是否实现System.IEquatable接口,如果是,则返回使用该实现的EqualityComparer。否则,它将返回一个EqualityComparer,使用T提供的Object.Equals和Object.GetHashCode的重写
您的类是否实现了自己的
Equals()
方法?它似乎除了
之外,而且只包含
参考平等性测试。您需要提供自己的IEqualityComparer
或Equals
实现。非常感谢。我使用了您的第一个建议并重写了GetHashCode()和Equals()。它正在工作。
public class Comparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.ID == y.ID; // or whatever defines your equality
}
public int GetHashCode(Person obj)
{
return obj.ID; // or whatever makes a good hash
}
}
var junior_handler_Unclaimed =
junior_handler_All.Except(junior_handler_Claimed, new Comparer()).ToArray();