所以我正在研究一个比较2个不同自定义对象列表的问题。我已经覆盖了object.Equals()并拥有以下类:
class Item
{
int ID;
string Name;
DayOfWeek[] days;
public overide Equals(object obj)
{
if(obj.GetType == GetType()
return this.Equals(obj)
return false;
}
public Equals(Item rhs)
{
if(this.ID == rhs.ID)
if(this.Name == rhs.Name)
if (this.days.OrderBy(i => i).SequenceEqual(rhs.days.OrderBy(i => i)))
return true;
return false;
}
}
使用以下代码时,我没有得到预期的结果:
List<Item> list1 = GetNewListFromDB();
List<Item> list2 = GetNewListFromDB();
//This is in a loop looking for changes to a table
//there is a delay between the list generation in the actual code
foreach(Item i in list1.Except(list2))
{
//DoStuff
}
直到我使用以下内容覆盖GetHashCode(我将其作为一个让它在墙上修复时抛出),它循环遍历list1中的所有项目。
public overide GetHashCode()
{
int dayHashCode = 0;
foreach(DayOfWeek d in days)
{
dayHashCode = dayHashCode ^ d.GetHashCode();
}
return this.ID.GetHashCode() ^ this.Name.GetHashCode() ^ dayHashCode
}
在我改编GetHashCode后,我得到了预期的结果。我一直在寻找,但无法找到List.Except如何实际比较集合中的对象的良好探索。我希望有人可以向新的程序员解释。
答案 0 :(得分:5)
Except
将第二个序列中的所有项放入基于散列的集合中,然后遍历第一个集合中的项目,将每个项目添加到集合中。此序列中的任何项目在添加时都不会在集合中存在。
使用这个基于散列的集合意味着对象需要对GetHashCode
和Equals
具有合理(且一致)的定义(在对象本身上,或通过{{ 1}}通过另一个重载)。