为什么List <t>的SequenceEqual返回false?</t>

时间:2013-02-19 12:57:41

标签: c# list comparison

当我遇到这样的情况时,我遇到sequenceEqual的问题:

Sentence s1 = new Sentence { Text = "Hi", Order = 1 };
Sentence s2 = new Sentence { Text = "Hello", Order = 2 };
List<Sentence> list1 = new List<Sentence> { s1, s2 };
List<Sentence> list2 = new List<Sentence> { s1, s2 };

这很好用

bool equal = list1.SequenceEqual(list2);

并返回true;

但是当我有一些返回List<Sentence>的方法时 例如:

public List<Sentence> Getall()
    {
        Sentence s1 = new Sentence { Text = "Hi", Order = 1 };
        Sentence s2 = new Sentence { Text = "Hello", Order = 2 };

        return new List<Sentence> { s1, s2 };
    }

并像这样使用它:

List<Sentence> list1 = Getall();
List<Sentence> list2 = Getall();

然后简单地检查一下

bool equal = list1.SequenceEqual(list2);

它返回'false',请告诉我为什么?以及如何使它工作?

3 个答案:

答案 0 :(得分:13)

您的问题是一个new Sentence { Text = "Hi", Order = 1 }不等于另一个new Sentence { Text = "Hi", Order = 1 }。虽然内容相同,但你有两个独立的对象,除非你设计了你的类,否则它们彼此并不相同,除非它们在字面上是相同的对象(如你的第一个例子)。

您的Sentence课程至少需要覆盖EqualsGetHashCode,此时您的SequenceEquals应该再次发挥作用。

答案 1 :(得分:10)

作为MSDN states here

  

通过使用类型的默认相等比较器比较元素来确定两个序列是否相等。

在您的情况下,

Sentence是一个默认为EqualsGetHashCode的引用类型,这意味着它将为每个元素使用引用相等。

您始终可以使用overload which accepts IEqualityComparer

答案 2 :(得分:1)

每次拨打Getall()时,您都会创建两个新的Sentence实例。在比较列表中的元素时,SequenceEqual将使用默认的相等比较器,它基本上只检查它们是否引用了sme对象:它们没有,因此它们是不同的。

您可以做的是覆盖序列中的Equal()==运算符,以便检查其他属性(如文本和顺序)。

或者,您可以撰写IEqualityComparer<Sequence>并将其传递给SequenceEqual