关于如何正确重写 object.GetHashCode() 的一般建议和指南

2024-01-10

根据MSDN http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx,哈希函数必须具有以下属性:

  1. 如果两个对象比较相等,则每个对象的 GetHashCode 方法必须返回相同的值。但是,如果两个对象比较不相等,则两个对象的 GetHashCode 方法不必返回不同的值。

  2. 只要不修改确定对象 Equals 方法返回值的对象状态,对象的 GetHashCode 方法就必须始终返回相同的哈希码。请注意,这仅适用于应用程序的当前执行,并且如果应用程序再次运行,则可以返回不同的哈希码。

  3. 为了获得最佳性能,哈希函数必须为所有输入生成随机分布。


我不断发现自己处于以下情况:我创建了一个类,并实现了IEquatable<T>并被覆盖object.Equals(object). MSDN http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx指出:

覆盖 Equals 的类型也必须覆盖 GetHashCode ;否则,Hashtable 可能无法正常工作。

然后它通常对我来说会有点停止。因为,你如何正确地覆盖object.GetHashCode()?永远不知道从哪里开始,而且似乎有很多陷阱。

在 StackOverflow 上,有很多与 GetHashCode 重写相关的问题,但其中大多数似乎都是针对非常特殊的情况和特定问题。因此,我想在这里得到一份好的汇编。包含一般建议和指南的概述。什么该做、什么不该做、常见陷阱、从哪里开始等等。

我希望它特别针对 C#,但我认为它对于其他 .NET 语言也将以同样的方式工作(?)。


我认为最好的方法可能是为每个主题创建一个答案,首先给出一个快速而简短的答案(如果可能的话,接近于一句台词),然后可能是一些更多信息,最后以相关问题、讨论、博客文章等结束。 ,如果有的话。然后,我可以创建一篇文章作为接受的答案(将其放在顶部),只需一个“目录”。尽量保持简短。不要只链接到其他问题和博客文章。尝试汲取它们的本质,然后链接到源(特别是因为源可能会消失)。另外,请尝试编辑和改进答案,而不是创建大量非常相似的答案。

我不是一个很好的技术作家,但我至少会尝试格式化答案,使它们看起来相似,创建目录等。我还将尝试在此处搜索一些相关问题,以回答部分问题这些也许可以提取出我能管理的那些的本质。但由于我在这个话题上不太稳定,所以我会尽量远离:p


目录

  • 我什么时候覆盖object.GetHashCode? https://stackoverflow.com/questions/1378686/general-advice-and-guidelines-on-how-to-properly-override-object-gethashcode/1378725#1378725

  • 为什么我必须重写 object.GetHashCode()? https://stackoverflow.com/questions/1378686/general-advice-and-guidelines-on-how-to-properly-override-object-gethashcode/1378796#1378796

  • GetHashCode 实现中看到的那些神奇数字是什么? https://stackoverflow.com/questions/1378686/general-advice-and-guidelines-on-how-to-properly-override-object-gethashcode/1378895#1378895


我希望涵盖但尚未涵盖的内容:

  • 如何创建整数(无论如何,如何将对象“转换”为 int 对我来说并不是很明显)。
  • What fields to base the hash code upon.
    • 如果它只应该在不可变字段上,那么如果只有可变字段怎么办?
  • How to generate a good random distribution. (MSDN Property #3)
    • 对此,似乎要选择一个很好的神奇素数(已经使用过 17、23 和 397),但是你如何选择它,它到底是做什么用的?
  • How to make sure the hash code stays the same all through the object lifetime. (MSDN Property #2)
    • 特别是当相等性基于可变字段时。 (MSDN 属性 #1)
  • How to deal with fields that are complex types (not among the built-in C# types http://msdn.microsoft.com/en-us/library/ya5y69ds.aspx).
    • 复杂的对象和结构、数组、集合、列表、字典、泛型类型等。
    • 例如,即使列表或字典可能是只读的,但这并不意味着它的内容是只读的。
  • How to deal with inherited classes.
    • 你应该以某种方式合并base.GetHashCode()到你的哈希码中?
  • 从技术上来说,你能偷懒并返回 0 吗?会严重违反 MSDN 准则 #3,但至少会确保 #1 和 #2 始终为真:P
  • 常见的陷阱和问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于如何正确重写 object.GetHashCode() 的一般建议和指南 的相关文章

随机推荐

  • 如何在 PrimeFaces 的工具提示上显示错误消息时摆脱空工具提示?

    我在某处显示错误消息
  • 如何在 R 中重置 par(mfrow)

    我设置了 par mfrow c 1 2 现在每次我绘制它时 它都会显示将其分成 2 个图 我怎样才能将其重置为仅显示一个图 非常感谢 您可以重置 mfrow 参数 par mfrow c 1 1
  • 阻止垃圾邮件发送者创建帐户(reCaptcha 不起作用)

    您好 我们刚刚在我们的电子邮件系统中注意到一堆尼日利亚垃圾邮件帐户 现在 我们的注册表单中确实有一个 reCaptcha 但显然他们手动或以其他方式绕过了它 这似乎是一种半手动规避 因为帐户不是批量创建的 而是以中间间隔几分钟的方式源源不断
  • enable_if:不带参数的 void 成员函数的最小示例

    我正在努力更好地理解std enable if在 C 11 中 并一直在尝试编写一个最小的示例 一个类A具有成员函数void foo 根据类型有不同的实现T来自类模板 下面的代码给出了所需的结果 但我还没有完全理解它 为什么版本V2工作 但
  • Double 数据类型,计算小数位后的小数

    下面的方法应该返回 这个 双精度 值有多少小数精度 尾随数字的数量 的答案 当值看起来像 5900 43 5900 043 等等时 我就猜对了 当该方法收到 5900 00 时 它返回 0 这是错误的 在我的需要中
  • 从单独的线程访问表单的控件

    我正在练习线程并遇到这个问题 情况是这样的 我在一个表单上有 4 个进度条 一个用于下载文件 一个用于显示页面加载状态等 我必须从单独的线程控制每个 ProgressBar 的进度 问题是我得到了无效操作异常其中说 跨线程操作无效 控制 p
  • 按引用传递引用与按值传递引用 - C#

    问候 我明白了按值传递和按引用传递之间的区别 但是通过 ref 传递引用 例如数组 和通过值传递数组是我似乎无法理解的 如何通过引用传递引用 int myArray 1 2 3 PassByVal myArray PassByRef ref
  • 什么时候不应该使用 React 备忘录?

    我一直在玩React 16 6 0最近我喜欢这个想法反应备忘录 但我一直无法找到有关最适合实现它的场景的任何内容 React 文档 https reactjs org docs react api html reactmemo https
  • 使用后置变量传递表数据

    基本上我有一个表 其中包含来自数据库的一堆数字 其中包含总计 小计列 我不打算将任何总数添加到数据库中 但我需要将总数从一页传递到下一页 我似乎无法使用 PHP 将它们作为后置变量正确传递 我想知道这是否是一个糟糕的策略 其次我应该做什么
  • 如何为角度反应形式的自定义验证器编写单元测试用例?

    我有一个自定义模型驱动的表单验证器来验证最大文本长度 export function maxTextLength length string return function control FormControl const maxLeng
  • 如何使用 Spring Data JPA 和 Hibernate 执行 H2 存储过程?

    我想使用 Spring Data JPA 和 Hibernate 来执行一个简单的 H2 数据库存储过程 存储过程类 public class H2StoredProcedures public static String stringIn
  • Java 正则表达式 (?i) 与 Pattern.CASE_INSENSITIVE

    我在用着 b w W 1 b 随着input input replaceAll regex 1 查找字符串中的重复单词并删除重复项 例如 字符串输入 for for for 将变为 for 然而 即使我使用过 它也无法将 Hello hel
  • @Value 变量在使用 @TestPropertySource 的单元测试中为 NULL

    在下面的单元测试中 我手动提供属性并尝试从现有的 YAML 资源文件中读取它们 尝试了不同的策略 TestPropertySource the Value 属性未设置 我总是为它们获取 NULL SpringBootConfiguratio
  • 当我在 flutter 应用程序中切换 appbar 时,如何使 webview 不重新加载?

    我希望当我在 flutter 应用程序中切换 appbar 时 webview 不重新加载 但我不知道该怎么做 很抱歉我是初学者 这是我录制的gif I searched on Google but I didn t find an ans
  • Excel vba - 禁用鼠标事件

    我正在开发一个Excel 2010工作簿 处于手动公式计算模式 文件 gt 选项 gt 公式 gt 工作簿计算 gt 手册 但是 我想要一些菜单选项来导致工作簿的重新计算 所以我使用以下代码 Private Sub Worksheet Ch
  • 突出显示 SWT 树节点中的特定字符串

    我有一个要求 首先要加载树 树包含 4 个级别 有一个文本字段 用户可以在其中输入 filterText 然后可以按搜索按钮 在树中 在四个级别中的任何一个中 如果与过滤器文本匹配 则该特定字符串仅应以黄色突出显示 而不是整个节点及其相应的
  • 如何阻止固定对象超出其父容器?

    我目前正在为学校制作一个网站 在该网站上我有一个带有链接的侧边栏 我希望它在侧面的任何地方都可见 所以我使用了position fixed 但现在它不再保留在其父级的空间内 而是从页面的最顶部开始 h1 text align center
  • 是否有一种校验和算法也支持从中“减去”数据?

    我有一个包含大约 1 亿个文档的系统 我想跟踪它们在镜像之间的修改 为了有效地交换有关修改的信息 我想按天发送有关修改文档的信息 而不是按每个单独的文档发送 像这样的事情 2012 03 26 cs26 2012 03 25 cs25 20
  • Android - 延迟加载图像

    我正在尝试伪造某种进度条 我有 X 张图片并想要一张ImageView以一定的延迟向他们展示 我尝试过做这样的事情 for i 2 i
  • 关于如何正确重写 object.GetHashCode() 的一般建议和指南

    根据MSDN http msdn microsoft com en us library system object gethashcode aspx 哈希函数必须具有以下属性 如果两个对象比较相等 则每个对象的 GetHashCode 方