【问题标题】:Implementing GetHashCode correctly [duplicate]正确实施 GetHashCode [重复]
【发布时间】:2012-02-19 01:16:24
【问题描述】:

我想听听社区的意见,我应该如何为我的对象实现 GetHashCode(或覆盖它)。我知道如果我覆盖 equals 方法,我需要这样做。我已经实现了很多次,有时只是调用基本方法。我知道如果我的对象包含相同的详细信息(成员),它应该等于该对象的另一个实例。从班级成员那里获取哈希码的最佳方法是什么?

【问题讨论】:

标签: c# .net equals


【解决方案1】:

假设您的班级如下所示:

class Frob {
    public string Foo { get; set; }
    public int Bar { get; set; }
    public double FooBar { get; set; }
}

假设您定义了 equals,如果 FooBar 相等,则 Frob 的两个实例相等,但 FooBar 无关紧要。

那么您应该根据FooBar 来定义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关键字不是必需的
猜你喜欢
  • 2021-12-12
  • 1970-01-01
  • 2011-02-22
  • 2012-03-08
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
相关资源
最近更新 更多