2009-04-25 74 views
5

在嘗試驗證自己時,C#等於IEnumerables是一個引用等於,我發現有些奇怪。隨着NUnit的C#Assert.AreNotEqual與Equals的比較

var a = (IEnumerable<string>)(new[] { "one", "two" }); 
var b = (IEnumerable<string>)(new[] { "one", "two" }); 

這個測試

Assert.IsFalse(a.Equals(b)); 

通行證以下設置,而本次測試

Assert.AreNotEqual(a, b); 

沒有。有人可以解釋爲什麼嗎?

編輯:謝謝你的答案。我剛剛閱讀了NUnit的文檔,它也說了同樣的事情,AreEqual和AreNotEqual與集合測試集合中每個元素的相等性。我想我被卡住了這個概念,AreEqual和AreNotEqual只是使用plain Equals。

回答

9

a.Equals(b)的調用返回false,因爲a和b不是相同的對象(儘管它們當然是相同的枚舉)。除非被覆蓋,否則Equals方法會自動通過對象的引用來比較對象,這就是在這種情況下發生的情況。

Assert.AreNotEqual比這個更聰明。它是爲調試目的而設計的,與Equals方法不同,因此它實際上比較了兩個枚舉產生的序列,因爲它將IEnumerable<T>識別爲特殊類型。您還應注意到它還有其他有趣的事情,例如當兩個參數在數字上相同但數值類型不同時返回true(例如shortlong)。

希望有所幫助。

1

我沒有看NUnit的源代碼,看NUnit的編碼是如何編碼的AreNotEqual。 但是,我可以告訴你它是如何爲具有相同行爲的MbUnit完成的。

首先在AssertNotEqual(A,B)如果檢查引用是通過執行這樣的代碼相同:

if (Object.ReferenceEquals(left, right)) 
     return true; 

在你的情況下,它會失敗。接下來檢查對象是否爲IEnumerable類型。如果是,則遍歷它們並比較項目是否相同且順序相同。

但是,IEnumerable中的T類型比MbUnit中的字符串或ValueType更復雜AssertNotEqaual(a,b)不會失敗。

var a = (IEnumerable<StringBuilder>)(new[] { new StringBuilder("one"), new StringBuilder("two") }); 
    var b = (IEnumerable<StringBuilder>)(new[] { new StringBuilder("one"), new StringBuilder("two") }); 

    Assert.IsFalse(a.Equals(b)); // Success 
    Assert.AreNotEqual(a, b);  // Success