首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IComparable和Equals()

IComparable和Equals()
EN

Stack Overflow用户
提问于 2009-09-14 12:37:49
回答 3查看 16K关注 0票数 11

来自MSDN

实现IComparable的类型必须覆盖覆盖等于的Equals.Types,也必须重写GetHashCode;否则,哈希表可能无法正常工作。

我不太明白。谁能解释一下。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-09-14 12:42:56

IComparable是一个接口,它定义了实现类的两个实例可以被视为大于、小于或等于彼此。由于您已经在该接口的方法中定义了相等,所以还需要覆盖相等方法(和相等操作符),以确保这两个方法的结果是一致的。

代码语言:javascript
复制
public class EqualityTest : IComparable<EqualityTest>
{
      public int Value { get; set; }

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

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

两个相同的项应该返回相同的哈希代码(用于快速查找哈希表中用作键的项),因此如果覆盖等于,则还应该覆盖GetHashCode()

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

代码语言:javascript
复制
public class EqualityTest
{
     public string A { get; set; }
     public string B { get; set; }
}

并运行Resharper的有用的“生成平等”函数说,我希望A和B同时影响平等。这是它创建的代码:

代码语言:javascript
复制
    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);
    }

因此,如果您是重写等于,那么您还应该定义上述所有内容以确保一致性,如果您正在实现IComparable,则同样适用。

票数 13
EN

Stack Overflow用户

发布于 2009-09-14 12:44:33

IComparable用于比较两个对象--如果它们被认为相等,则比较将返回0。如果IComparable.Compare为两个对象返回零,而obj1.Equals(obj2)返回false,这将是非常意外的,因为这意味着对象具有两种不同的相等含义。

当类重写等于时,它也应该重写GetHashCode,因为两个相等的对象应该散列为相同的值,并且这个散列应该基于在实现相等时使用的字段/属性。

票数 1
EN

Stack Overflow用户

发布于 2009-09-14 12:43:49

代码中的对象可以通过两种方式进行比较:EqualsGetHashCode

为了在所有情况下正确地比较对象,当您重写Equals方法(用于某些比较)时,还必须重写GetHashCode (其余部分中使用)。

如果您根据您的代码覆盖其中一个而不是另一个,您可能会得到意想不到的结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1421289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档