首页 文章

小班的好哈希? (覆盖GetHashCode)

提问于
浏览
4

我使用一些包含1-2个int的标识类/结构,也可以是日期时间或小字符串 . 我将它们用作字典中的键 .

对于像这样的东西,GetHashCode的优秀覆盖是什么?一些非常简单但仍然有点高效的希望 .

谢谢

2 回答

  • 1

    这个SO问题的公认答案是我使用的技术 .

    What is the best algorithm for an overridden System.Object.GetHashCode?

  • 1

    看看Essential C# .

    它包含有关如何正确覆盖 GetHashCode() 的详细说明 .

    从书中摘录

    哈希码的目的是通过生成对应于对象值的数字来有效地 balancer 哈希表 . 必需:等于对象必须具有相等的哈希码(如果a.Equals(b),则a.GetHashCode()== b.GetHashCode())必需:GetHashCode()在特定对象的生命周期内返回应该是常量(相同的值),即使对象的数据发生变化 . 在许多情况下,您应该缓存方法返回以强制执行此操作 . 必需:GetHashCode()不应抛出任何异常; GetHashCode()必须始终成功返回值 . 性能:哈希代码应尽可能唯一 . 但是,由于哈希代码只返回一个int,因此对于具有可能比int可以容纳的值更多的值的对象,哈希代码必须重叠 - 几乎所有类型 . (一个明显的例子很长,因为有更多可能的长值而不是int可以唯一标识 . )性能:可能的哈希码值应该在int的范围内均匀分布 . 例如,创建一个不考虑基于拉丁语的字符串分布主要以最初的128个ASCII字符为中心这一事实的哈希会导致字符串值的分布非常不均匀,并且不会是强大的GetHashCode()算法 . 性能:GetHashCode()应针对性能进行优化 . 如果哈希码不同,则GetHashCode()通常在Equals()实现中用于短路完全等于比较 . 因此,当类型用作字典集合中的键类型时,经常会调用它 . 性能:两个对象之间的微小差异应该导致哈希码值之间的巨大差异 - 理想情况下,对象中的1位差异导致哈希码的大约16位平均变化 . 这有助于确保散列表保持 balancer ,无论它如何“散列”散列值 . 安全性:攻击者很难制作具有特定哈希码的对象 . 攻击是使用大量数据填充散列表,这些数据都散列到相同的值 . 然后,哈希表实现变为O(n)而不是O(1),从而导致可能的拒绝服务攻击 .

    正如这里已经提到的,你还要考虑一些关于覆盖 Equals() 的要点,并且有一些代码示例显示了如何实现这两个函数 .

    因此,这些信息应该给出一个起点,但我建议购买这本书并阅读完整的第9章(至少前12个方面),以获得关于如何正确实现这两个关键功能的所有要点 .

相关问题