当与IEnumerable的&LT处理的NUnit Assert.AreNotEqual不正确的行为; T>?不正确、行为、NUnit、LT

2023-09-05 00:08:56 作者:思念在倒带

使用NUnit 2.5.9,下面的测试意外失败:

Using NUnit 2.5.9, the following test unexpectedly fails:

[TestFixture]
public class FooTest
{
    [Test]
    public void Inequality()
    {
        var first = new Foo(new[] { 1 }, 2);
        var second = new Foo(new[] { 1 }, 3);

        Assert.AreNotEqual(first, second);
    }
}

public struct Foo : IEnumerable<int>, IEquatable<Foo>
{
    private readonly IEnumerable<int> values;

    public int Bar { get; private set; }

    public Foo(IEnumerable<int> values, int bar)
        : this()
    {
        this.values = values;
        Bar = bar;
    }

    public IEnumerator<int> GetEnumerator()
    {
        return values.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public bool Equals(Foo other)
    {
        return other.values.SequenceEqual(values) && other.Bar == Bar;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }
        if (obj.GetType() != typeof(Foo))
        {
            return false;
        }
        return Equals((Foo)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((values != null ? values.GetHashCode() : 0) * 397) ^ Bar;
        }
    }

    public static bool operator ==(Foo left, Foo right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(Foo left, Foo right)
    {
        return !left.Equals(right);
    }
}

挖掘到NUnit的code,事实证明,当NUnit的遇到一个实现IEnumerable两个对象,它只是比较了两个集合,并在对象上忽略任何其他属性。

Digging into the NUnit code, it turns out that when NUnit encounters two objects that implement IEnumerable, it just compares the two collections and ignores any other properties on the objects.

这感觉我错了:一个对象实现一个特定的接口不局限于仅在执行该角色的事实。或者是.NET IEnumerable接口的特殊情况?还是我刚才误会NUnit的?

This feels wrong to me: the fact that an object implements a particular interface does not limit it to only performing that role. Or is the IEnumerable interface in .NET a special case? Or have I just misunderstood NUnit?

推荐答案

看起来这是在NUnit的一个错误,因为据我了解,这将是固定在3.0版本。下面有一个可能的工作围绕实施一些讨论的IComparer&LT; T&GT;

Looks like this is a bug in NUnit, as far as I understand it would be fixed in 3.0 version. Below some discussion with a possible work around implementing IComparer<T>:

等式约束和IEnumerable混乱 NUnit的bug跟踪系统:使用覆盖的IEnumerables,集合等等于 Equality constraints and IEnumerable confusion NUNit bug tracker: Use overridden Equals for IEnumerables, Collections, etc.