c# - IComparable 和 Equals()

标签 c#

来自 MSDN

Types that implement IComparable must override Equals.Types that override Equals must also override GetHashCode; otherwise, Hashtable might not work correctly.

我不是很明白。谁能解释一下。

最佳答案

IComparable 是一个接口(interface),它定义了实现类的两个实例可以被视为大于、小于或等于彼此。由于您已在该接口(interface)的方法中定义了相等性,因此您还需要重写 Equals 方法(和相等性运算符)以确保两者的结果一致。

public class EqualityTest : IComparable<EqualityTest>
{
      public int Value { get; set; }

      public int CompareTo(EqualityTest other)
      {
           return this.Value.CompareTo(other.Value);
      }
}

在上面的示例中,我实现了 IComparable,但没有覆盖 Equals。如果您使用具有相同值的类的两个单独实例调用 CompareTo,它会说它们相等。如果您用相同的两个实例调用 Equals,它会说它们相等,因为它会测试它们是否是同一个对象(Equals 的默认实现)。

两个相等的项目应该返回相同的哈希码(用于快速查找用作哈希表中的键的项目)所以如果你覆盖 Equals 那么你也应该覆盖 GetHashCode()


例如,我刚刚在我的 IDE 中创建了以下类:

public class EqualityTest
{
     public string A { get; set; }
     public string B { get; set; }
}

然后运行 ​​Resharper 的有用“生成平等”功能,说我希望 A 和 B 都影响平等。这是它创建的代码:

    public bool Equals(EqualityTest other)
    {
        if (ReferenceEquals(null, other))
        {
            return false;
        }

        if (ReferenceEquals(this, other))
        {
            return true;
        }

        return Equals(other.A, A) && Equals(other.B, B);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }

        if (ReferenceEquals(this, obj))
        {
            return true;
        }

        if (obj.GetType() != typeof(EqualityTest))
        {
            return false;
        }

        return Equals((EqualityTest)obj);
    }

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

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

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

因此,如果您要覆盖 Equals,那么您还应该定义以上所有内容以确保一致性,如果您要实现 IComparable,则同样适用。

关于c# - IComparable 和 Equals(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1421289/

相关文章:

c# - 有没有关于 Lucene.NET 的书籍

c# - 网络应用程序上的计时器

c# - String.Join 丢弃空值返回的项目少于数组中的元素数

c# - 导出到 excel 在服务器上不起作用

c# - 如何从 SelectionModel 外部的 Ext.Net.GridPanel 中的当前选定行获取值?

c# - C# 中使用 Rijndael 解密

c# - 使服务返回大量数据

c# - 当我尝试添加图像时,MVC 总是返回 null

c# - ASP.Net - 如何在使用登录控件登录前加密密码

c# - 指定了无效的 DN 语法 - Visual Studio 错误