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

时间:2010-07-08 13:40:45

标签: c# gethashcode

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

对于像这样的东西,GetHashCode的优秀覆盖是什么?有些东西很简单,但仍然有点高效。

由于

2 个答案:

答案 0 :(得分:1)

查看Essential C#

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

从书中摘录

  

哈希码的目的是通过生成与对象值对应的数字来有效地平衡哈希表

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

如前所述,您还要考虑一些有关覆盖Equals()的要点,并且有一些代码示例显示了如何实现这两个函数。

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

答案 1 :(得分:1)

这个问题的答案是我使用的技术。

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