首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >覆盖GetHashCode()

覆盖GetHashCode()
EN

Stack Overflow用户
提问于 2012-07-14 05:27:01
回答 3查看 5.2K关注 0票数 20

这篇文章中,Jon提到他通常使用这种算法来重写GetHashCode()。

代码语言:javascript
复制
public override int GetHashCode()
{
  unchecked // Overflow is fine, just wrap
  {
    int hash = 17;
    // Suitable nullity checks etc, of course :)
    hash = hash * 23 + Id.GetHashCode();
    return hash;
  }
}

现在,我尝试使用这个方法,但是Resharper告诉我,方法GetHashCode()应该只使用只读字段进行散列(尽管它编译得很好)。什么是一个很好的练习,因为现在我真的不能把我的字段变成只读的?

我尝试用Resharper生成这个方法,结果如下。

代码语言:javascript
复制
public override int GetHashCode()
{
  return base.GetHashCode();
}

老实说,这没什么用.

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-14 06:18:31

如果所有字段都是可变的,并且必须实现GetHashCode方法,那么恐怕这就是您需要的实现。

代码语言:javascript
复制
public override int GetHashCode() 
{ 
    return 1; 
} 

是的,这是低效的,但这至少是正确的。

问题是,字典和GetHashCode集合正在使用HashSet将每一项放在一个桶中。如果哈希代码是基于一些可变字段计算的,并且在将对象放入HashSet或Dictionary之后,这些字段确实发生了更改,则不能再从HashSet或Dictionary中找到该对象。

注意,由于所有对象返回相同的HashCode 1,这基本上意味着所有对象都放在HashSet或字典中的同一个桶中。因此,“HashSet”或“字典”中总是只有一个桶。当试图查找对象时,它将对唯一桶内的每个对象执行相等检查。这就像在链接列表中搜索一样。

有人可能会说,如果我们能够确保在添加到hashcode或Dictionary集合中的对象之后不会更改字段,那么实现基于可变字段的哈希代码可能会很好。我个人的看法是,这是容易出错的。两年后接管您的代码的人可能不会意识到这一点,并意外地破坏了代码。

票数 18
EN

Stack Overflow用户

发布于 2012-07-14 15:39:22

请注意,您的GetHashCode必须与您的相等方法并驾齐驱。如果您只需要使用引用相等(当您从来没有两个可以相等的类的不同实例时),那么您就可以安全地使用从对象继承的相等和GetHashCode。这将比简单地使用return 1 (来自GetHashCode )要好得多。

票数 5
EN

Stack Overflow用户

发布于 2013-10-29 09:54:53

我个人倾向于在没有不可变字段的类中,为GetHashCode()的每个实现返回一个不同的数值。这意味着,如果我有一个包含不同实现类型的字典,就有可能将不同类型的不同实例放入不同的桶中。

例如

代码语言:javascript
复制
public class A
{
    // TODO Equals override

    public override int GetHashCode()
    {
        return 21313;
    } 
}

public class B
{
    // TODO Equals override

    public override int GetHashCode()
    {
        return 35507;
    } 
}

然后,如果我有一个包含Dictionary<object, TValue>实例的AB和其他类型的实例,那么查找的性能将比所有GetHashCode的实现返回相同的数值要好。

还应该注意的是,我利用素数得到了更好的分布。

根据注释,我提供了一个LINQPad示例这里,它演示了对不同类型使用return 1与为每种类型返回不同值之间的性能差异。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11481323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档