C#Assert.AreNotEqual与Equals

时间:2009-04-25 22:13:04

标签: c# nunit equals

在尝试验证自己时,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。

2 个答案:

答案 0 :(得分:9)

a.Equals(b)的调用返回false,因为a和b不是同一个对象(尽管它们当然是相同的枚举)。除非被覆盖,否则Equals方法会自动按对象引用比较对象,这就是本例中发生的情况。

Assert.AreNotEqual比这更聪明一点。它设计用于调试目的,与Equals方法不同,因此它实际上比较了两个枚举产生的序列,因为它将IEnumerable<T>识别为特殊类型。您还应该注意到它会执行其他有趣的操作,例如当两个参数在数值上相同但具有不同的值类型(例如trueshort)时返回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