編寫一個好的 GetHashCode 覆蓋

GetHashCode 對 Dictionary <>和 HashTable 有重要的效能影響。

好的 GetHashCode 方法

  • 應該有均勻的分佈
    • 每個整數應該具有大致相等的返回隨機例項的機會
    • 如果你的方法為每個例項返回相同的整數(例如常量'999’),你將會有不好的表現
  • 應該很快
    • 這些不是加密雜湊,其中慢是一個特徵
    • 雜湊函式越慢,字典就越慢
  • 必須在 Equals 計算為 true 的兩個例項上返回相同的 HashCode
    • 如果他們不這樣做(例如因為 GetHashCode 返回一個隨機數),則可能無法在 ListDictionary 或類似物品中找到物品。

實現 GetHashCode 的一個好方法是使用一個素數作為起始值,並將型別欄位的雜湊碼加上其他素數乘以:

public override int GetHashCode()
{
    unchecked // Overflow is fine, just wrap
    {
        int hash = 3049; // Start value (prime number).

        // Suitable nullity checks etc, of course :)
        hash = hash * 5039 + field1.GetHashCode();
        hash = hash * 883 + field2.GetHashCode();
        hash = hash * 9719 + field3.GetHashCode();
        return hash;
    }
}

只有 Equals 方法中使用的欄位才應用於雜湊函式。

如果你需要以不同的方式為 Dictionary / HashTables 處理相同的型別,則可以使用 IEqualityComparer。