程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Effective C#原則10:明白GetHashCode()的缺陷(2)

Effective C#原則10:明白GetHashCode()的缺陷(2)

編輯:關於C語言

規則1表示,兩 個相等的對象(用操作符==定義的)必須返回相同的散列值。這一規則被大多數值 類型遵守著,但你可以破壞它, just as you could with for reference types. ValueType的操作符==()與其它成員一起來比較結構的第一個字段。這是 滿足第一條規則的。只要在任何時候你所重寫的==操作符用第一個字段,這將可 以正常工作。任何不以第一個字段斷定相等的結構將違反這一規則,從而破壞 GetHashCode().

第二條規則表示,散列值必須是實例不變的。這一規則 只有當結構的第一個成員字段是恆定類型時才被遵守。如果第一個字段的值發生 了改變,那麼散列值也會發生改變。這就破壞了這規則。是的,如果你的結構的 實例對象在它的生存期內改變了結構的第一個字段,那麼GetHashCode()就破壞 了這一規則。這也就是另一個原因,你最好的原則就是把值類型設置為恆定類型 (參見原則7)。

第三個規則依懶於第一個字段以及是如何使用它的。如果 你的第一個字段能保證產生一個在整型范圍上的隨機分布,並且第一個字段的分 布能復蓋結構的所有其它值,那麼這個結構就很好的保證了一個均衡的分布(譯 注:就是說結構的第一個字段可以唯一的決定一個實例)。然而,如果第一個字 段經常具有相同的值,那麼這一規則也會被破壞。考慮對前面的結構做一個小的 修改:

public struct MyStruct
{
 private DateTime _epoch;
 private string  _msg;
 private int    _id;
}

如果_epoch字段設置的是當前日期(不包含時間) ,所有在同一給定日期裡創建的對象具有相同的散列值。這防礙了在所有散列值 中進行均衡的分布。

概括一個默認的行為,Object.GetHashCode()可以 正確的在引用類型上工作,盡管它不是必須保證一個高效的分布。(如果你有一 個對Object的==操作符的重載,你會破壞GetHashCode())。 ValueType.GetHashCode()僅在你的結構的第一個字段是只讀的時候才能正確工 作。而當你的結構的第一個字段的值,復蓋了它所能接受的輸入的有意義的子集 時,ValueType.GetHashCode()就可以保證一個高效的散列值。

如果你准 備創建一個更好的散列值,你須要為你的類型建立一些約束。再次驗證上面的三 條規則,現在我們來實現一個可工作的GetHashCode()。

首先,如果兩個 對象相等,就是由操作符==所定義的,它們必須返回同樣的散列值。類型的任何 承擔散列值的屬性或者數據值也必須參與相等比較。顯然,這就意味著同樣用於 相等比較的的屬性也用於散列值的生成。然而很可能所有與相等比較的屬性,並 不用於散列值的計算。System.ValueType的默認行為就是這樣的,也就是說它經 常違反規則3。同樣的數據元素應該參同時參與兩個運算(比較和散列)。

第二條規則就是GetHashCode()返回的值必須是實例不變的。想象你已經了一個 引用類型,Customer:

public class Customer
{
  private string _name;
 private decimal _revenue;
 public Customer( string name )
 {
  _name = name;
 }
 public string Name
 {
  get { return _name; }
   set { _name = value; }
 }
 public override int GetHashCode()
 {
  return _name.GetHashCode();
 }
}

假設你運行下面的代碼片斷:

Customer c1 = new Customer( "Acme Products" );
myHashMap.Add( c1, orders );
// Oops, the name is wrong:
c1.Name = "Acme Software";

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved