【问题标题】:Is there a way to make .NET Core GetHashCode deterministic有没有办法让 .NET Core GetHashCode 具有确定性
【发布时间】:2017-05-02 04:44:54
【问题描述】:

我只是浪费了几个小时的调试时间,然后才意识到与 .NET 相反,在 .NET Core 中,每次运行代码时 GetHashCode 都会返回不同的值。 我完全理解这样做的理由。依赖哈希码值是一个非常糟糕的主意(比如序列化它们)。我什至记得 Microsoft 的 .NET 内部构建(在 Core 之前)会改变 GetHashCode 的每次构建行为,因此没有人对它感到太舒服。

说了这么多,我目前正在调试大量使用 GetHashCode 的复杂代码。我知道这个错误是我自己做的,与 GetHashCode 无关,但每次我运行它时,它都会在其他地方失败。很烦人。 有没有办法强制 GetHashCode 表现得像在 .NET 中一样(在我调试时),而不必编写我自己的哈希函数并且不必在我的代码中到处替换它?

【问题讨论】:

  • 您的意思是String.GetHashCode() 还是Object.GetHashCode()?我认为您根本无法影响后者。它总是基于对象引用,它永远是伪确定性的。前者在编译时由FEATURE_RANDOMIZED_STRING_HASHING 管理,在运行时由<UseRandomizedStringHashAlgorithm> 管理——但我不知道.NET Core 是否尊重后者,只是默认情况下它肯定是开启的。
  • 澄清一下,当我说“编译时”时,我的意思是在编译 runtime 时,而不是你自己的应用程序。在您自己的代码中定义FEATURE_RANDOMIZED_STRING_HASHING 没有任何作用。但是 .NET Core 是开源的,如果涉及到,您总是可以重新构建它。
  • 我的代码是通用的,所以实际上它是 object.GetHashCode() 但在我的示例中,对象是一个字符串,因此哈希码基于(不可变的)字符串内容。

标签: .net-core


【解决方案1】:

根据docs,只有框架的变化才会改变哈希结果。我也偶然发现了这一点。我的解决方案是创建自己的哈希算法。只需几分钟,因为我不需要任何花哨的东西。

private static int GetSimpleHash(string s)
{
    return s.Select(a => (int)a).Sum();
}

附带说明,我已经提交了 dotnet core 1.1 的错误。 (字符串).GetHashCode()here.

更新

哈希值可能会因框架或域而改变。这意味着同一程序的两次后续运行可能会返回不同的结果。
唉,我的错误报告没有实际意义,而是改为文档更新。

更新更新

文档已更新,更加清晰。

【讨论】:

    【解决方案2】:

    我发现让 string.GetHashCode 在多次执行中返回可预测值的实用解决方案只是切换回经典的 .NET (4.6)。由于我的代码没有特定于 .NET Core 的内容,因此我要做的唯一工作就是创建一个新项目。我在 .NET 4.6 下调试了我的代码,修复了错误并切换回 Core。

    【讨论】:

      猜你喜欢
      • 2019-06-09
      • 2022-08-16
      • 1970-01-01
      • 2019-06-11
      • 2020-10-29
      • 2011-04-15
      • 2020-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多