2013-02-19 86 views
4

您好我有一些问题sequenceEqual时,我有这样的情况:为什么序列等于列表<T>返回false?

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); 

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

+1

。在第一种情况下,它们与两个不同的*引用*完全相同。 – bytefire 2013-02-19 13:02:32

回答

8

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

您的Sentence类需要覆盖EqualsGetHashCode,至少在此时SequenceEquals应该再次工作。

+0

非常好,它现在工作,thx – 2013-02-19 13:15:59

+0

这个答案是接近的,但PatrykĆwiek的答案,推荐使用IEqualityComparer是我的解决方案。 – Sidney 2016-04-21 21:04:48

9

作为MSDN states here

确定两个序列是否是通过使用默认的相等比较器为它们的类型由比较元件相等。

Sentence你的情况是使用默认EqualsGetHashCode引用类型,这意味着它将使用的每个元素的参照平等。

您可以随时使用overload which accepts IEqualityComparer

+1

关于使用比较器而不是定义类本身的行为的可能性的好处。 – Rawling 2013-02-19 13:04:06

0

您正在创建句每次调用Getall()时间两个新实例。当比较列表中的元素时,SequenceEqual将使用默认的相等比较器,它基本上只检查它们是否指向sme对象:它们不是,所以它们是不同的。

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

或者,也可以写一个IEqualityComparer<Sequence>并且因为在第二个方案中它们是不同的对象,即,它们的GetHash()方法返回不同的值传递给SequenceEqual