C# - 具有接口(interface)类型列表的相等运算符未按预期工作

标签 c# collections operators equals equality

考虑以下代码,其中 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.");

相等运算符返回 false(即列表不匹配),此外 operator ==operator !=Equals(ClassOne) Equals(object)GetHashCode() 已为 ClassOne 实现/覆盖。这是为什么?我希望相等运算符返回 true。 == 运算符是否必须实现任何其他方法/接口(interface)才能按预期工作?

作为引用,下面是 ClassOneIClass 的实现:

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

任何正确方向的帮助或提示都将不胜感激。谢谢。

最佳答案

Why is that? I would expect the equality operator to return true.

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

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

if (list.SequenceEqual(list2))
    Console.WriteLine("Lists are equal.");
else
    Console.WriteLine("Lists are NOT equal.");

关于C# - 具有接口(interface)类型列表的相等运算符未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41495792/

相关文章:

c# - 如何获取特定的套接字并关闭它

javascript - 根据从 MSSQL 数据库检索的数值在 div 中动态创建星形字形 C#

java - 用于将声明更改为 java 集合接口(interface)而不是具体实现的插件

c - =+(等于加号)在 C 语言中是什么意思?

python - Pycharm 与使用相等运算符执行的 None 比较

c# - C# 中的简单循环(移动平均)数组

c# - revEng 命令现在需要提供程序。应该通过什么?

c# - WCF - 不要序列化(发出)空集合

c# - 为什么 C# 不为集合实现 GetHashCode?

java - Java 中具有负字节值的 >> 和 >>> 运算符