给定以下类
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(); } }我已经覆盖了 Equals 方法,因为 Foo 代表 Foo 表的一行.哪个是覆盖 GetHashCode 的首选方法?
I have overridden the Equals method because Foo represent a row for the Foos table. Which is the preferred method for overriding the GetHashCode?
为什么覆盖 GetHashCode 很重要?
Why is it important to override GetHashCode?
推荐答案是的,如果您的项目将用作字典中的键,或者 HashSet 等,这一点很重要 -因为这用于(在没有自定义 IEqualityComparer 的情况下)将项目分组到桶中.如果两个项目的哈希码不匹配,它们可能永远被认为是相等的 (Equals 将永远不会被调用.
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. If the hash-code for two items does not match, they may never be considered equal (Equals will simply never be called).
GetHashCode() 方法应该反映Equals 逻辑;规则是:
The GetHashCode() method should reflect the Equals logic; the rules are:
- 如果两件事相等 (Equals(...) == true) 那么它们必须为 GetHashCode()
- 如果GetHashCode() 相等,则它们不必相同;这是一个碰撞,Equals 将被调用以查看它是否是真正的相等.
- if two things are equal (Equals(...) == true) then they must return the same value for GetHashCode()
- if the GetHashCode() is equal, it is not necessary for them to be the same; this is a collision, and Equals will be called to see if it is a real equality or not.
在这种情况下,看起来 "return FooId;" 是一个合适的 GetHashCode() 实现.如果您正在测试多个属性,通常使用如下代码组合它们,以减少对角线冲突(即 new Foo(3,5) 与 具有不同的哈希码new Foo(5,3)):
In this case, it looks like "return FooId;" is a suitable GetHashCode() implementation. If you are testing multiple properties, it is common to combine them using code like below, to reduce diagonal collisions (i.e. so that new Foo(3,5) has a different hash-code to 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; }哦 - 为方便起见,您还可以考虑在覆盖 Equals 和 GetHashCode 时提供 == 和 != 运算符代码>.
Oh - for convenience, you might also consider providing == and != operators when overriding Equals and GetHashCode.
当你弄错时会发生什么的演示是 这里.
A demonstration of what happens when you get this wrong is here.
更多推荐
为什么在重写 Equals 方法时重写 GetHashCode 很重要?
发布评论