C#Assert.AreNotEqual与Equals
在尝试validation自己时,对于IEnumerables的C#Equals是一个引用等于,我发现了一些奇怪的东西。 在NUnit中进行以下设置
var a = (IEnumerable)(new[] { "one", "two" }); var b = (IEnumerable)(new[] { "one", "two" });
这个测试
Assert.IsFalse(a.Equals(b));
通过,而这个测试
Assert.AreNotEqual(a, b);
没有。 任何人都可以解释原因吗?
编辑:谢谢你的回答。 我刚刚阅读了NUnit的文档,它说同样的事情,AreEqual和AreNotEqual with collections测试集合中每个元素的相等性。 我想我坚持这个概念,AreEqual和AreNotEqual只是使用普通的Equals。
对a.Equals(b)
的调用返回false
因为a和b不是相同的对象(尽管它们当然是相同的枚举)。 除非被覆盖,否则Equals
方法会自动通过引用来比较对象,这就是本例中发生的情况。
Assert.AreNotEqual
比这更聪明一点。 它设计用于调试目的,与Equals
方法不同,因此它实际上比较了两个枚举产生的序列,因为它将IEnumerable
识别为特殊类型。 您还应该注意到它会执行其他有趣的操作,例如当两个参数在数值上相同但具有不同的值类型(例如, short
和long
)时返回true
。
希望有所帮助。
我没有看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)(new[] { new StringBuilder("one"), new StringBuilder("two") }); var b = (IEnumerable )(new[] { new StringBuilder("one"), new StringBuilder("two") }); Assert.IsFalse(a.Equals(b)); // Success Assert.AreNotEqual(a, b); // Success