gpt4 book ai didi

c# - 为什么 Visual Studio 将 "-1937169414"添加到生成的哈希码计算中?

转载 作者:行者123 更新时间:2023-12-03 14:40:33 24 4
gpt4 key购买 nike

如果您使用 Visual Studio 自己的重构菜单将 GetHashCode 实现添加到这样的类:

Generate GetHashCode menu

并选择类中唯一的 int 属性:

Member selection screen

它在 .NET Framework 上生成此代码:

public override int GetHashCode()
{
return -1937169414 + Value.GetHashCode();
}

(它在 .NET Core 上生成 HashCode.Combine(Value),我不确定它是否涉及相同的值)

这个值有什么特别之处?为什么 Visual Studio 不使用 Value.GetHashCode()直接地?据我了解,它并没有真正影响哈希分布。由于它只是加法,连续的值仍然会累积在一起。

编辑:我只用 Value 尝试了不同的类属性,但显然属性名称会影响生成的数字。例如,如果您将该属性重命名为 Halue ,数字变为 387336856。感谢 Gökhan Kurt 指出这一点。

最佳答案

如果您在 Microsoft 的存储库中查找 -1521134295,您会发现它出现了很多次

  • https://github.com/search?q=org%3Amicrosoft+%22-1521134295%22+OR+0xa5555529&type=Code
  • https://github.com/search?q=org%3Adotnet++%22-1521134295%22+OR+0xa5555529&type=Code

  • 大部分搜索结果都在 GetHashCode函数中,但都有如下形式
    int hashCode = SOME_CONSTANT;
    hashCode = hashCode * -1521134295 + field1.GetHashCode();
    hashCode = hashCode * -1521134295 + field2.GetHashCode();
    // ...
    return hashCode;

    第一个 hashCode * -1521134295 = SOME_CONSTANT * -1521134295 将由生成器在生成期间或在编译期间由 CSC 预乘。这就是代码中 -1937169414 的原因

    深入研究结果揭示了代码生成部分,可以在函数 CreateGetHashCodeMethodStatements 中找到
    const int hashFactor = -1521134295;

    var initHash = 0;
    var baseHashCode = GetBaseGetHashCodeMethod(containingType);
    if (baseHashCode != null)
    {
    initHash = initHash * hashFactor + Hash.GetFNVHashCode(baseHashCode.Name);
    }

    foreach (var symbol in members)
    {
    initHash = initHash * hashFactor + Hash.GetFNVHashCode(symbol.Name);
    }

    如您所见,哈希取决于符号名称。在该函数中,常量也称为 permuteValue ,可能是因为在乘法之后,位以某种方式排列
    // -1521134295
    var permuteValue = CreateLiteralExpression(factory, hashFactor);

    如果我们以二进制形式查看值,则有一些模式: 101001 010101010101010 101001 0100110100 1010101010101010 10100 10100 1 。但是如果我们将任意值与它相乘,就会有很多重叠的进位,所以我看不出它是如何工作的。输出也可能有不同数量的设置位,所以它不是真正的排列

    您可以在 Roslyn 的 AnonymousTypeGetHashCodeMethodSymbol 中找到另一个生成器,它调用常量 HASH_FACTOR
    //  Method body:
    //
    // HASH_FACTOR = 0xa5555529;
    // INIT_HASH = (...((0 * HASH_FACTOR) + GetFNVHashCode(backingFld_1.Name)) * HASH_FACTOR
    // + GetFNVHashCode(backingFld_2.Name)) * HASH_FACTOR
    // + ...
    // + GetFNVHashCode(backingFld_N.Name)

    选择该值的真正原因尚不清楚

    关于c# - 为什么 Visual Studio 将 "-1937169414"添加到生成的哈希码计算中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61517881/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com