自定义类型GetHashCode

可能重复:
什么是重写的System.Object.GetHashCode的最佳算法?

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

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

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


最好的办法是避免任何会产生相同哈希码的东西,如果你:

  • 交换操作数的顺序
  • 有一个大部分为零的值,并且只是移动非零值
  • 在这些帐户上添加(本身)和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;
        }
    }
    

    无论你在代码中使用加法还是异或都是争论的话题,我都看到两个例子都没有明确分析哪个更好(即均匀分布)。 挑一个,并与它一起去。

    397是ReSharper插件在生成GetHashCode实现时使用的默认值,显然选择它是因为它通常溢出整型的范围并因此将比特位混合得更好。 关于GetHashCode实现的这种特殊格式有许多理论,但它是最常用的一种。


    我总是使用排他或(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();
        }
    }
    

    如果你想确保切换字符串的值给出不同的结果。 有各种各样的可以用于散列的方法(例如通用散列),所以只要搜索散列方法,如果这就是你想要的。

    链接地址: http://www.djcxy.com/p/39755.html

    上一篇: Custom type GetHashCode

    下一篇: Implementing GetHashCode