深入研究ValueType.GetHashCode 的怪異之處:一個可能不變的值
圍繞ValueType.GetHashCode 的本機實現方式的陰謀() 計算值類型的雜湊碼是不可否認的。讓我們透過檢查特定範例及其意外結果來解開這個謎團。
考慮以下結構的兩個實例:
struct TheKey { public int id; public string Name; }
為 Name 欄位分配不同的值,我們預期它們的雜湊程式碼不同。然而,輸出揭示了一個驚人的現實:
var k1 = new TheKey(17, "abc"); var k2 = new TheKey(17, new string(new[] { 'a', 'b', 'c' })); Console.WriteLine("hash1={0}", k1.GetHashCode()); Console.WriteLine("hash2={0}", k2.GetHashCode()); // Output: // hash1=346948941 // hash2=346948941
儘管字串引用不同,k1 和 k2 都產生相同的雜湊程式碼。
揭開機制
ValueType.GetHashCode() 的本機實作透過極為複雜的機制進行操作。首先,它確定結構是否包含引用類型引用或欄位間隙。如果這兩個條件都不存在,它將對所有值的位元執行有效的位元異或運算,從而有效地將所有欄位組合到雜湊碼中。然而,這種方法並不普遍適用。
當存在引用類型或間隙時,程式碼會開始逐個欄位遍歷,搜尋可用的欄位 - 值類型或非空物件參考。一旦找到,該欄位的雜湊碼與方法表指標進行異或,形成最終的雜湊碼。
揭開神秘面紗
在我們的範例中,可用欄位恰好是 id。儘管字串欄位的值不同,但它會被忽略,導致 k1 和 k2 具有相同的 id,因此具有相同的雜湊碼。
結論
了解這種非常規行為增強了為雜湊碼計算精心設計值類型的重要性。避免僅依賴 CLR 的預設實作是至關重要的。透過明確定義雜湊碼計算,開發者可以確保其值類型的雜湊碼的唯一性和一致性。
以上是為什麼結構體中的不同字串參考會出現相同的 ValueType.GetHashCode() 結果?的詳細內容。更多資訊請關注PHP中文網其他相關文章!