2010-06-20 56 views
1

所以,我需要建立在C#中的結構,將作爲一個重要成(相當大)的字典,看起來就像這樣:C#:優化字典訪問(在關鍵結構哈希)

private readonly IDictionary<KeyStruct, string> m_Invitations; 

問題是,我真的需要一個結構來作爲關鍵字,因爲它只能通過兩個獨立的數據項來識別條目,其中一個數據項可以是一個空(不僅是空的!)字符串。

我需要在結構上實現什麼?你將如何去創建哈希?散列衝突(偶然性)會嚴重影響性能還是可以忽略不計?

我在問,因爲這是「內循環」代碼。

回答

4

如果您有resharper,您可以使用Alt-Ins - > Equality成員生成這些方法。

這裏是生成的代碼爲您KeyStruct:

public struct KeyStruct : IEquatable<KeyStruct> 
{ 
    public string Value1 { get; private set; } 
    public long Value2 { get; private set; } 

    public KeyStruct(string value1, long value2) 
     : this() 
    { 
     Value1 = value1; 
     Value2 = value2; 
    } 

    public bool Equals(KeyStruct other) 
    { 
     return Equals(other.Value1, Value1) && other.Value2 == Value2; 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (obj.GetType() != typeof (KeyStruct)) return false; 
     return Equals((KeyStruct) obj); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      return ((Value1 != null ? Value1.GetHashCode() : 0)*397)^Value2.GetHashCode(); 
     } 
    } 

    public static bool operator ==(KeyStruct left, KeyStruct right) 
    { 
     return left.Equals(right); 
    } 

    public static bool operator !=(KeyStruct left, KeyStruct right) 
    { 
     return !left.Equals(right); 
    } 
} 
2

您需要實施(覆蓋)兩種方法。
1. bool Equals(object)
2. int GetHashCode()

哈希碼不必是唯一的,但少不同對象將返回相同的散列碼性能越好,你都會有。

您可以使用類似:

public int GetHashCode() 
{ 
    int strHash = str == null ? 0 : str.GetHashCode(); 
    return ((int)lng*397)^strHash; 
} 
3

如果KeyStruct是結構(與結構C#關鍵字聲明),不要忘了重載Equals和GetHash碼的方法,或提供自定義的IEqualityComparer到詞典構造,因爲ValueType.Equals方法的默認實現使用Reflection來比較兩個結構實例的內容。

它傾向於使KeyStruct不可變,如果你這樣做,你可以計算結構實例哈希一次,然後簡單地從GetHashCode方法返回它。但是這可能是不成熟的優化,取決於你需要多久才能按鍵獲得價值。

通常,使用結構作爲詞典鍵是可以的。

或者你在問如何實現GetHashCode方法?

+0

是的,它主要是關於我如何將着手實施一個高效的GetHashCode() - 方法,不是在速度方面,但在「數據方面選擇」。 我現在知道,我有兩個字段,一個是字符串(可以爲null,這是一個非常重要的要求,因爲我正在和一個遺留系統交談),另一個字段很長。 – StormianRootSolver 2010-06-20 15:43:21

+0

只需提供struct的哈希碼作爲結構數據哈希碼的組合(如sum或xor)。例如: 公衆覆蓋INT的GetHashCode() { uncheked //防止算術溢出 { 返回StringComparer.OrdinalIgnoreCase.GetHashCode(_myFirstField)+ EqualityComparer .Default.GetHashCode(_myLongField); } } – STO 2010-06-20 15:48:03

+0

可能有意義把它放到你的答案中。 – ChaosPandion 2010-06-20 15:51:31