代码之家  ›  专栏  ›  技术社区  ›  Boris

C#断言。不相等与相等

  •  5
  • Boris  · 技术社区  · 17 年前

    当我试图向自己验证C#Equals for IEnumerous是一个引用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与集合一起测试集合中每个元素的相等性。我想我一直坚持这样一种观点,即AreEqual和AreNotEqual只是使用普通的等号。

    2 回复  |  直到 17 年前
        1
  •  9
  •   Noldorin    17 年前

    a.Equals(b) 回报 false 因为a和b不是相同的对象(尽管它们当然是相同的枚举)。这 Equals 除非被重写,否则方法会自动根据对象的引用进行比较,这就是本例中发生的情况。

    Assert.AreNotEqual 比这聪明一点。它是为调试目的而设计的,与 方法,因此它实际上比较了两次枚举产生的序列,因为它识别 IEnumerable<T> 作为一种特殊类型。您还应该注意到它还有其他有趣的功能,例如返回 true 当两个参数在数值上相同但值类型不同时(例如。 short long ).

    希望这能有所帮助。

        2
  •  1
  •   Vadim    17 年前

    我没有查看NUnit的源代码来了解NUnit人员是如何编码AreNotEqual的。 然而,我可以告诉你,对于具有相同行为的MbUnit是如何做到的。

    首先,在AssertNotEqual(a,b)中,通过执行以下代码来检查引用是否相等:

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

    就你而言,它会失败的。接下来,它检查对象是否为IEnumerable类型。如果是,迭代它们并比较项目是否相同以及顺序是否相同。

    但是,IEnumerable中的T类型比MbUnit中的字符串或ValueType更复杂。AssertNotEqaual(a,b)中的ValueType不会失败。

        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