【问题标题】:Custom type GetHashCode [duplicate]自定义类型 GetHashCode [重复]
【发布时间】:2011-06-30 21:46:17
【问题描述】:

可能重复:
What is the best algorithm for an overridden System.Object.GetHashCode?

我需要为由三个字符串组成的类型覆盖 GetHashCode 方法。这是我的代码:

protected override int GetHashCode()
{
    return str1.GetHashCode() + str2.GetHashCode() + str3.GetHashCode();
}

这种方法实现的安全方式是什么?

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    最好的方法是避免任何会产生相同哈希码的事情,如果您:

    • 交换了操作数的顺序
    • 有一个大部分为零的值,只是移动非零值

    这些帐户的加法(单独)和 XOR 均失败。

    这里有一个更好的方法:

    public override int GetHashCode()
    {
        unchecked
        {
            int result = 37; // prime
    
            result *= 397; // also prime (see note)
            if (str1 != null)
                result += str1.GetHashCode();
    
            result *= 397;
            if (str2 != null)
                result += str2.GetHashCode();
    
            result *= 397;
            if (str2 != null)
                result += str2.GetHashCode();
    
            return result;
        }
    }
    

    您是否在该代码中使用加法或 XOR 有待商榷,我见过使用这两种方法的示例,但没有明确分析哪个更好(即均匀分布)。选择一个并使用它。

    397 是ReSharper addin when it generates GetHashCode implementations 使用的默认值,显然被选中是因为它通常会溢出 int 的范围,因此可以更好地混合位。围绕这种特定格式的 GetHashCode 实现有很多理论,但它是最常用的一种。

    【讨论】:

      【解决方案2】:

      我总是使用异或(Xor)而不是加法,因为它不倾向于在任何地方获取数字(比如大值)。所以我会这么说

      protected override int GetHashCode()
      { return str1.GetHashCode() ^ str2.GetHashCode() ^ str3.GetHashCode(); }
      

      是一个更好的实现。

      你也可以尝试改变它,比如

      protected override int GetHashCode()
      {
          unchecked
          {
              return (str1.GetHashCode() * 1369) ^
                     (str2.GetHashCode() * 37) ^ str3.GetHashCode();
          }
      }
      

      如果您想确保切换字符串的值会产生不同的结果。有各种各样的方法可用于散列(例如universal hashing),所以如果您正在寻找,只需搜索散列方法即可。

      【讨论】:

      • 第二种形式需要用unchecked包围。
      • 好点...我会改变它,谢谢。 (虽然默认不勾选也不一定。)
      • 您不想依赖此代码的任何默认值。
      猜你喜欢
      • 1970-01-01
      • 2021-07-20
      • 2013-10-24
      • 2021-10-17
      • 2021-04-21
      • 2021-10-24
      • 2015-02-03
      • 2015-05-09
      • 1970-01-01
      相关资源
      最近更新 更多