根据MSDN http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx,哈希函数必须具有以下属性:
-
如果两个对象比较相等,则每个对象的 GetHashCode 方法必须返回相同的值。但是,如果两个对象比较不相等,则两个对象的 GetHashCode 方法不必返回不同的值。
-
只要不修改确定对象 Equals 方法返回值的对象状态,对象的 GetHashCode 方法就必须始终返回相同的哈希码。请注意,这仅适用于应用程序的当前执行,并且如果应用程序再次运行,则可以返回不同的哈希码。
-
为了获得最佳性能,哈希函数必须为所有输入生成随机分布。
我不断发现自己处于以下情况:我创建了一个类,并实现了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(使用前将#替换为@)