首页 > C# > 为什么在覆盖等于方法时重写 GetHashCode 很重要?

为什么在覆盖等于方法时重写 GetHashCode 很重要?

上一篇 下一篇

给定以下类

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();
    }
}

我已经覆盖了该方法,因为表示 s 表的一行。覆盖 ?EqualsFooFooGetHashCode

为什么覆盖很重要?GetHashCode

分割线

网友回答:

实际上很难正确实现,因为除了 Marc 已经提到的规则之外,哈希代码在对象的生命周期内不应更改。因此,用于计算哈希代码的字段必须是不可变的。GetHashCode()

当我与NHibernate合作时,我终于找到了这个问题的解决方案。
我的方法是根据对象的 ID 计算哈希代码。ID 只能通过构造函数设置,因此如果您想更改 ID(这不太可能),您必须创建一个具有新 ID 的新对象,因此需要一个新的哈希代码。此方法最适合 GUID,因为可以提供随机生成 ID 的无参数构造函数。

分割线

网友回答:

是的,如果您的项目将用作字典中的键,或者等,这很重要 – 因为这用于(在没有自定义的情况下)将项目分组到存储桶中。如果两个项目的哈希码不匹配,则它们可能永远不会被视为相等(永远不会调用 Equals)。HashSet<T>IEqualityComparer<T>

GetHashCode() 方法应该反映逻辑;规则是:Equals

  • 如果两个东西相等 (),那么它们必须返回相同的值Equals(...) == trueGetHashCode()
  • 如果相等,则它们不必相同;这是一个碰撞,将被调用以查看它是否是真正的平等。GetHashCode()Equals

在这种情况下,看起来 “” 是一个合适的实现。如果要测试多个属性,通常使用如下所示的代码将它们组合在一起,以减少对角线冲突(即具有不同的哈希代码):return FooId;GetHashCode()new Foo(3,5)new Foo(5,3)

在现代框架中,该类型具有帮助您从多个值创建哈希代码的方法;在较旧的框架上,你需要没有,所以像这样:HashCode

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;
}

哦 – 为了方便起见,您还可以考虑在覆盖和 .==!=EqualsGetHashCode


这里演示了当你弄错时会发生什么。

分割线

网友回答:

通过覆盖等于,您基本上表明您更知道如何比较给定类型的两个实例。

下面你可以看到ReSharper如何为你编写GetHashCode()函数的例子。请注意,此代码段旨在由程序员进行调整:

public override int GetHashCode()
{
    unchecked
    {
        var result = 0;
        result = (result * 397) ^ m_someVar1;
        result = (result * 397) ^ m_someVar2;
        result = (result * 397) ^ m_someVar3;
        result = (result * 397) ^ m_someVar4;
        return result;
    }
}

如您所见,它只是尝试根据类中的所有字段猜测一个好的哈希代码,但是如果您知道对象的域或值范围,您仍然可以提供更好的哈希代码。

模板简介:该模板名称为【为什么在覆盖等于方法时重写 GetHashCode 很重要?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 202次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 02-10
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
企业网站 html5 自适应 响应式 微信图片 微信公众平台 微信文章 单页式简历模板 微信模板 微信素材
您可能会喜欢的其他模板