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
.
(哦,为方便起见,在覆盖Equals
和GetHashCode
时,您可能还考虑提供==
和!=
运算符。)
A demonstration of what happens when you get this wrong is here .
(当你得到这个错误会发生什么情况的演示是在这里 。)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…