C#:覆盖GetHashCode,这段代码有什么作用?

时间:2011-10-01 13:09:16

标签: c# nhibernate gethashcode

以下是我在Nhibernate 3 Beginners Guide中找到的覆盖GetHashCode的代码。我不明白为什么它使用结果* 397.如果397只是一个随机数他用来产生独特的结果??

我们可以只使用GetHashCode获取firstname,middlename和lastname,然后使用^将它们组合在一起,它还应该生成一个唯一的结果。

public override int GetHashCode()
{
   unchecked
   {
       var result = FirstName.GetHashCode();
       result = (result*397) ^ (MiddleName != null ? MiddleName.GetHashCode() : 0);
       result = (result*397) ^ LastName.GetHashCode();
       return result;
   }
}

2 个答案:

答案 0 :(得分:7)

将中间哈希码乘以给定数字作为每个组合的一部分将意味着组合代码的排序不会无关紧要。

如果你只是做了一个独家或三个名字部分,那么“John William James”将提供与“James William John”相同的哈希码。

选择

397是因为它是一个足够大的素数,足以导致哈希码溢出,这有助于生成散列码的良好分布。

溢出是此代码必须位于unchecked块内的原因。

答案 1 :(得分:1)

乘法也基本上是位移(如果*的幂为2,则精确位移),因此它对计算值产生这种影响,但至于为什么精确地为397,那就是这个特殊的哈希算法是如何编写的。是的,其他值,实际上更复杂的算法通常用作散列算法。

这不同于简单地将3个哈希码一起异或,并且将导致更少的“哈希冲突” - 其中2个(或更多个)对象散列到相同的值(如果在良好的散列函数中不能避免,则最小化的东西)

相关问题