2013-02-19 42 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