在尝试验证自己时,IEnumerables的C#Equals是一个引用等于,我发现了一些奇怪的东西。在NUnit中进行以下设置
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 with collections测试集合中每个元素的相等性。我想我坚持这个概念,AreEqual和AreNotEqual只是使用普通的Equals。
答案 0 :(得分:9)
对a.Equals(b)
的调用返回false
,因为a和b不是同一个对象(尽管它们当然是相同的枚举)。除非被覆盖,否则Equals
方法会自动按对象引用比较对象,这就是本例中发生的情况。
Assert.AreNotEqual
比这更聪明一点。它设计用于调试目的,与Equals
方法不同,因此它实际上比较了两个枚举产生的序列,因为它将IEnumerable<T>
识别为特殊类型。您还应该注意到它会执行其他有趣的操作,例如当两个参数在数值上相同但具有不同的值类型(例如true
和short
)时返回long
。
希望有所帮助。
答案 1 :(得分:1)
我没有看NUnit源代码,看看NUnit的人是如何编写AreNotEqual的。 但是,我可以告诉你如何为MbUnit做同样的行为。
首先在AssertNotEqual(a,b)中通过执行如下代码来检查引用是否相等:
if (Object.ReferenceEquals(left, right))
return true;
在你的情况下,它会失败。接下来,它检查对象是否为IEnumerable类型。如果是,则迭代它们并比较项目是否相同且顺序相同。
然而,在IE中,Tnumerable中的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