2016-12-16 87 views
7

我只是浪费了几个小时的调试之后才意识到与.NET相反,在.NET Core中,GetHashCode在您每次运行代码时都返回不同的值。 我完全理解这个理由。依靠哈希码值是一个非常糟糕的想法(如序列化它们)。我甚至记得微软的.NET内部版本(Core之前)会改变每个版本的GetHashCode的行为,以免让人感到不适应。尽管如此,我目前正在调试大量使用GetHashCode的复杂代码。我知道这个bug是我自己做的,并且与GetHashCode无关,但是每次运行它时,它都会在其他地方失败。很烦人。 有没有办法强制GetHashCode行为像.NET中(而我正在调试),而不必编写我自己的散列函数,并必须在我的代码中的任何地方取代它?有没有办法让.NET核心GetHashCode确定性

+1

你的意思是'String.GetHashCode()'或'Object.GetHashCode()'?我认为你根本不会影响后者;它总是基于永远不会超过伪确定性的对象引用。前者在编译时由'FEATURE_RANDOMIZED_STRING_HASHING'管理,在运行时由['UseRandomizedStringHashAlgorithm>](https://msdn.microsoft.com/library/jj152924)管理 - 但我不知道.NET Core是否尊重后者,只是默认情况下它是绝对开启的。 –

+0

为了澄清,当我说“编译时”时,我的意思是在编译* runtime *的时候,而不是你自己的应用程序。在你自己的代码中定义'FEATURE_RANDOMIZED_STRING_HASHING'什么都不做。但.NET Core是开源的,如果说到这一点,你可以随时重建它。 –

+0

我的代码是泛型的,实际上它是object.GetHashCode(),但在我的例子中,对象是一个字符串,所以哈希代码基于(不可变的)字符串内容。 –

回答

0

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

2

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

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

在旁注中,我提出了一个dotnet核心1.1的bug。 (string).GetHashCode()here

更新

散列可以改变由于框架或域。这意味着同一程序的两个后续运行可以返回不同的结果。
唉,我的错误报告没有实际意义,而改为文档更新。

相关问题