GetHashCode() 僅用於雜湊容器(Hashtable、Dictionary)的鍵值物件。基類實作對參考型別正確但低效,對實值型別常錯誤。若型別不作鍵值,完全不用覆寫;若必須作鍵值,務必正确实作滿足三大鐵律。
a == b → a.GetHashCode() == b.GetHashCode()。GetHashCode() 必須恆定回傳相同值。int 範圍均勻分佈,確保雜湊桶負載平衡。==)。== 則必須覆寫 GetHashCode(),否則違反規則 1。== 也基於第一欄位比較時成立。public class Customer
{
private readonly string _name; // 不可變
private decimal _revenue; // 可變,不可參與雜湊
public Customer(string name) { _name = name; }
public string Name => _name;
public Customer ChangeName(string newName) => new Customer(newName); // 不可變模式
public override int GetHashCode() => _name.GetHashCode();
}
public override int GetHashCode()
{
unchecked // 避免溢位檢查效能損失
{
int hash = 17;
hash = hash * 23 + _field1.GetHashCode();
hash = hash * 23 + _field2.GetHashCode();
// 排除可變欄位、事件、委派等
return hash;
}
}
若實值型別作鍵值,整個結構必須不可變(參見原則 7)。否則使用者修改欄位會導致雜湊碼改變,物件在表中丟失;或因裝箱產生副本,修改副本不影響表中原物件,行為詭異難除錯。
GetHashCode() 滿足三大鐵律,同步覆寫 Equals() 與 ==(參見原則 9)。