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识别为特殊类型。 您还应该注意到它会执行其他有趣的操作,例如当两个参数在数值上相同但具有不同的值类型(例如, shortlong )时返回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