C# 列表如何<;T>;。除了比较项目?

C# 列表如何<;T>;。除了比较项目?,c#,C#,因此,在比较两个不同的自定义对象列表的问题上,我得到了一个有趣的观察结果。我有一个overiden object.Equals()并有以下类: class Item { int ID; string Name; DayOfWeek[] days; public overide Equals(object obj) { if(obj.GetType == GetType() return this.Equals(ob

因此,在比较两个不同的自定义对象列表的问题上,我得到了一个有趣的观察结果。我有一个overiden 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进行了过度编码之后,我得到了预期的结果。我一直在寻找,但找不到一个很好的解释列表。除了实际比较集合中的对象。我希望有人能向更新的程序员解释一下。

除了
之外,将第二个序列中的所有项放入一个基于哈希的集合,然后遍历第一个集合中的项,将每个项添加到集合中。此序列中添加时集合中不存在的任何项都将被生成


使用此基于哈希的集合意味着对象需要对
GetHashCode
Equals
进行合理(一致)的定义(在对象本身上,或者通过另一个重载传递的
IEqualityComparer
).

除外
将第二个序列中的所有项目放入基于哈希的集合,然后遍历第一个集合中的项目,并将每个项目添加到集合中。此序列中添加时集合中不存在的任何项都将被生成


使用此基于哈希的集合意味着对象需要对
GetHashCode
Equals
进行合理(一致)的定义(在对象本身上,或者通过另一个重载传递的
IEqualityComparer
).

它使用一个集合,该集合首先使用
GetHashCode
:但也提到了它。始终实现/重写这两个函数,
Equals
GetHashCode
。Microsoft建议您在重写
Equals
时重写
GetHashCode
。这是MSDN上实现Equals页面指南的第一个要点
EqualityComparer.Default
,它依次依赖于
IEquatable.Equals
或重写
object.Equals
object.GetHashCode
。您的代码违反了
Equals
的约定,因为它与
GetHashCode
@CraigW不一致。注意:这不仅仅是一个建议——如果您重写
Equals
,而不是
GetHashCode
,编译器将发出警告。这就是为什么您从不忽略编译器警告的原因。:-)旁注:标题的正确答案应该是“列表。除了不比较项目,因为没有这样的方法”。。。请考虑为今后的问题提供有效的方法名称。请注意,文档明确指出,
Except
通过比较器使用自定义对象的
Equals
GetHashCode
。它使用一个集合,该集合首先使用
GetHashCode
:但也提到了它。始终实现/重写这两个函数,
Equals
GetHashCode
。Microsoft建议您在重写
Equals
时重写
GetHashCode
。这是MSDN上实现Equals页面指南的第一个要点
EqualityComparer.Default
,它依次依赖于
IEquatable.Equals
或重写
object.Equals
object.GetHashCode
。您的代码违反了
Equals
的约定,因为它与
GetHashCode
@CraigW不一致。注意:这不仅仅是一个建议——如果您重写
Equals
,而不是
GetHashCode
,编译器将发出警告。这就是为什么您从不忽略编译器警告的原因。:-)旁注:标题的正确答案应该是“列表。除了不比较项目,因为没有这样的方法”。。。请考虑为今后的问题提供有效的方法名称。请注意,文档明确指出,
Except
通过比较器使用自定义对象的
Equals
GetHashCode
。这是@capnhector No的实现,它使用这两种操作,正如我在回答中明确指出的那样。@capnhector No,它同时使用这两种操作。如果不同时使用这两种方法,它就不在乎定义是否一致,它只需要一个合理的
GetHashCode
实现。正如我在回答中特别指出的那样,这两种方法都需要有一个合理的定义。它需要这样做,因为它同时使用这两种方法。如果它不需要这两种操作,它就不需要对这两种操作都进行合理的定义。下面是@capnhector No的实现,它使用这两种操作,正如我在回答中明确指出的那样。@capnhector No,它同时使用这两种操作。如果不同时使用这两种方法,它就不在乎定义是否一致,它只需要一个合理的
GetHashCode
实现。正如我在回答中特别指出的那样,这两种方法都需要有一个合理的定义。它需要这样做,因为它同时使用这两种方法。如果它不需要两者,它就不需要对两者进行合理的定义。
public overide GetHashCode()
{
    int dayHashCode = 0;
    foreach(DayOfWeek d in days)
    {
        dayHashCode = dayHashCode ^ d.GetHashCode();
    }

    return this.ID.GetHashCode() ^ this.Name.GetHashCode() ^ dayHashCode 
}