C# - 具有接口类型列表的相等运算符无法按预期工作

Str*_*zel 1 c# collections equality equals operators

请考虑以下代码,其中ClassOne的类派生自IClass:

List<IClass> list = new List<IClass>();
list.Add(new ClassOne("foo", "bar"));
list.Add(new ClassOne("baz", "bam"));

List<IClass> list2 = new List<IClass>();
list2.Add(new ClassOne("foo", "bar"));
list2.Add(new ClassOne("baz", "bam"));

if (list == list2)
    Console.WriteLine("Lists are equal.");
else
    Console.WriteLine("Lists are NOT equal.");
Run Code Online (Sandbox Code Playgroud)

等于运算符返回false(即表不匹配),除了事实的operator ==,operator !=,Equals(ClassOne),Equals(object)GetHashCode()已实施/被重写ClassOne.这是为什么?我希望等于运算符返回true.是否还有其他方法/接口必须实现才能使==操作员按预期工作?

供参考,这里是ClassOne和的实现IClass:

public interface IClass
{
    string getA();
    string getB();
} //interface


public class ClassOne : IClass, IEquatable<ClassOne>
{
    public ClassOne(string a, string b)
    {
        strA = a;
        strB = b;
    }

    public string getA()
    {
        return strA;
    }

    public string getB()
    {
        return strB;
    }

    public bool Equals(ClassOne other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        if (!string.Equals(strA, other.strA))
            return false;
        return string.Equals(strB, other.strB);
    }

    public override bool Equals(object other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        if (other is ClassOne)
        {
            ClassOne c1 = (ClassOne)other;
            return Equals(c1);
        }
        //not ClassOne, so it is not equal
        return false;
    }

    public override int GetHashCode()
    {
        int hc_a = -1;
        if (null != strA)
            hc_a = strA.GetHashCode();
        int hc_b = -1;
        if (null != strB)
            hc_b = strB.GetHashCode();
        return hc_a ^ hc_b;
    }

    public static bool operator ==(ClassOne left, ClassOne right)
    {
        if (ReferenceEquals(left, right)) return true;
        if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
            return false;
        return left.Equals(right);
    }

    public static bool operator !=(ClassOne left, ClassOne right)
    {
        return !(left == right);
    }

    private string strA, strB;
} //class
Run Code Online (Sandbox Code Playgroud)

任何有关正确方向的帮助或提示都将受到赞赏.谢谢.

D S*_*ley 8

这是为什么?我希望等于运算符返回true.

不正确 - 未定义==运算符(和Equals())List<T>以检查其内容的相等性 - 它默认为从定义的运算符引用相等性object.由于这两个列表是不同的对象,因此==返回false.

您可以使用Linq SequenceEqual方法确定两个列表是否包含相同顺序的相等对象:

if (list.SequenceEqual(list2))
    Console.WriteLine("Lists are equal.");
else
    Console.WriteLine("Lists are NOT equal.");
Run Code Online (Sandbox Code Playgroud)

  • 不.`Equals`也没有被覆盖.你需要使用Linq的`SequenceEquals`或其他一些机制. (4认同)