2009-05-26 56 views
1

的構造函數的hashCode我有不可變類型的HashCode的一些問題。產生不可變型

  • 我可以「pre」 - 在構造函數中生成不可變類型的HashCode,還是有什麼理由不這樣做?
  • 當我調用方法GetHashCode()時,我是否應該再次生成Hashcode?

Here's樣本類:

public class Id { 

     private readonly object _value; 

     private readonly int _hash = -1; 


     public Id(object value) { 
      _value = value; 
      _hash = (int) (7 * value.GetType().GetHashCode() + 7 + 7 * _value.GetHashCode()); 
     } 

     public object Value { 
      get { 
      return _value; 
      } 
     } 

     public override int GetHashCode() { 
      return _hash; 
     } 

     public override bool Equals(object obj) { 
      Id other = obj as Id; 

      if (other == null) { 
      return false; 
      } 

      return this.GetHashCode() == other.GetHashCode(); 
     } 
     } 
+0

爲什麼用這種計算散列碼的複雜方法? – 2009-05-26 13:24:28

+0

這只是一個例子。我在i-net的某個地方發現了這個代碼。我認爲這不是生成哈希碼的最佳方法。 – Jehof 2009-05-27 06:02:36

回答

8

您可以預生成散列碼,但爲什麼呢?只需在需要時生成它(在GetHashCode),然後可能存儲它 - 大多數對象從不需要有散列,因此它只會減慢程序。

當我調用方法GetHashCode()時,我應該總是再次生成哈希碼嗎?

不可變對象的哈希碼應該始終相同,因此無論是再次生成還是存儲它,除了存儲都會提高性能之外,它不應該有任何影響。

注意:您shouln't通過比較哈希碼定義Equals - 兩個不同的對象可能有平等的哈希碼(哈希collsion)。

1

理由不預生成:它會減慢對象的創建。

原因始終再生:您保存到保持的哈希碼各地所需的存儲。

爲了記錄,我可能會預先計算哈希碼並將其存儲爲不可變的對象,除非分析顯示我很昂貴,而且我沒有經常訪問該值。

3

這真的取決於用例。

你使用的哈希很多嗎?然後預生成它,因爲對象是不可變的,每次計算它都是不必要的,因爲結果總是相同的。

是不是哈希用了很多?那麼不要預生成它,因爲它會不必要地減慢程序的速度,計算可能不會被使用的散列。

第三(和最好的,在我看來)選項來計算GetHashCode的散列和緩存結果,計算散列只有一次,以後每次都返回這個緩存的哈希值。這樣,沒有時間計算散列,因爲它從未被使用,也不會在每次調用GetHashCode時進行不必要的計算。儘管這確實意味着內存被用來將哈希存儲在對象中。