2016-12-16 40 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

更新

散列可以改變由於框架或域。這意味着同一程序的兩個後續運行可以返回不同的結果。
唉,我的錯誤報告沒有實際意義,而改爲文檔更新。

相關問題