Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
430 views
in Technique[技术] by (71.8m points)

c# - 当覆盖Equals方法时,覆盖GetHashCode为什么很重要?(Why is it important to override GetHashCode when Equals method is overridden?)

Given the following class

(鉴于以下课程)

public class Foo
{
    public int FooId { get; set; }
    public string FooName { get; set; }

    public override bool Equals(object obj)
    {
        Foo fooItem = obj as Foo;

        if (fooItem == null) 
        {
           return false;
        }

        return fooItem.FooId == this.FooId;
    }

    public override int GetHashCode()
    {
        // Which is preferred?

        return base.GetHashCode();

        //return this.FooId.GetHashCode();
    }
}

I have overridden the Equals method because Foo represent a row for the Foo s table.

(我已经覆盖了Equals方法,因为Foo代表的一排Foo桌上。)

Which is the preferred method for overriding the GetHashCode ?

(重写GetHashCode的首选方法是?)

Why is it important to override GetHashCode ?

(重写GetHashCode为什么很重要?)

  ask by David Basarab translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yes, it is important if your item will be used as a key in a dictionary, or HashSet<T> , etc - since this is used (in the absence of a custom IEqualityComparer<T> ) to group items into buckets.

(是的,将您的项目用作字典或HashSet<T>等中的键非常重要-因为使用该项目(在没有自定义IEqualityComparer<T> )将项目分组到存储桶中。)

If the hash-code for two items does not match, they may never be considered equal ( Equals will simply never be called).

(如果两个项目的哈希码不匹配,则可能永远不会认为它们相等(永远不会调用Equals )。)

The GetHashCode() method should reflect the Equals logic;

(GetHashCode()方法应反映Equals逻辑;)

the rules are:

(规则是:)

  • if two things are equal ( Equals(...) == true ) then they must return the same value for GetHashCode()

    (如果两个条件相等( Equals(...) == true ),则它们必须GetHashCode()返回相同的值)

  • if the GetHashCode() is equal, it is not necessary for them to be the same;

    (如果GetHashCode()是相等的, 没有必要对他们是相同的;)

    this is a collision, and Equals will be called to see if it is a real equality or not.

    (这是一次碰撞,将调用Equals来查看它是否是真正的相等性。)

In this case, it looks like " return FooId; " is a suitable GetHashCode() implementation.

(在这种情况下,看起来“ return FooId; ”是合适的GetHashCode()实现。)

If you are testing multiple properties, it is common to combine them using code like below, to reduce diagonal collisions (ie so that new Foo(3,5) has a different hash-code to new Foo(5,3) ):

(如果要测试多个属性,通常使用如下代码将它们组合在一起,以减少对角线冲突(即, new Foo(3,5)的哈希码与new Foo(5,3)哈希码不同):)

unchecked // only needed if you're compiling with arithmetic checks enabled
{ // (the default compiler behaviour is *disabled*, so most folks won't need this)
    int hash = 13;
    hash = (hash * 7) + field1.GetHashCode();
    hash = (hash * 7) + field2.GetHashCode();
    ...
    return hash;
}

Oh - for convenience, you might also consider providing == and != operators when overriding Equals and GetHashCode .

(哦,为方便起见,在覆盖EqualsGetHashCode时,您可能还考虑提供==!=运算符。)


A demonstration of what happens when you get this wrong is here .

(当你得到这个错误会发生什么情况的演示是在这里 。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...