正确实施 GetHashCode [重复]
Posted
技术标签:
【中文标题】正确实施 GetHashCode [重复]【英文标题】:Implementing GetHashCode correctly [duplicate] 【发布时间】:2012-02-19 01:16:24 【问题描述】:我想听听社区的意见,我应该如何为我的对象实现 GetHashCode(或覆盖它)。我知道如果我覆盖 equals 方法,我需要这样做。我已经实现了很多次,有时只是调用基本方法。我知道如果我的对象包含相同的详细信息(成员),它应该等于该对象的另一个实例。从班级成员那里获取哈希码的最佳方法是什么?
【问题讨论】:
考虑作为***.com/a/720282/93922的副本关闭 在做这件事之前,我建议你阅读并理解我关于它的文章:blogs.msdn.com/b/ericlippert/archive/2011/02/28/… 谢谢,我知道这可能是一个常见问题,我应该多做一点。感谢您的帮助 @Fildor:在这里:ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode @EricLippert 太棒了,谢谢! 【参考方案1】:假设您的班级如下所示:
class Frob
public string Foo get; set;
public int Bar get; set;
public double FooBar get; set;
假设您定义了 equals,如果 Foo
和 Bar
相等,则 Frob
的两个实例相等,但 FooBar
无关紧要。
那么您应该根据Foo
和Bar
来定义GetHashCode
。一种方法是这样的:
return this.Foo.GetHashCode() * 17 + this.Bar.GetHashCode();
基本上,您只想合并定义相等性的所有字段。一种方法是像我所做的那样不断累积并乘以 17。它快速、简单、正确,而且通常可以提供良好的分布。
【讨论】:
我觉得这本身应该是一个问题,但为什么是 23? 也许会指出 GetHashCode 只告诉你两个对象是否可能被认为是相等的。仍然存在哈希冲突的可能性。 在实现GetHashCode()
(和Equals()
)时要小心,因为它依赖于可变数据,就像这里一样。如果您将此类对象放入基于哈希的字典中,然后对其进行变异,则该字典将不再正常工作。理想情况下,GetHashCode()
(和Equals()
)应该只依赖于不可变数据。
我认为计算应该用 unchecked
关键字包装,就像这样:unchecked(this.Foo.GetHashCode() * 17 + this.Bar.GetHashCode())
。总和可能大于 int.MaxValue。
@Quintus:我的立场是正确的。当分配Bar = int.MaxValue; Foo = "something"
,运行GetHashCode()
函数并且没有unchecked
关键字时,代码将运行并产生一个负哈希码并且不会崩溃,所以unchecked
关键字不是必需的以上是关于正确实施 GetHashCode [重复]的主要内容,如果未能解决你的问题,请参考以下文章