2011-07-30 13 views
0

私のクラスの1つに対してEqualsメソッドをオーバーライドします。以下はDictionaryアイテムのGetHashCode

public override bool Equals (object obj) 
    { 
     ... 
     // compare to make sure all <key, value> pair of this.dict have 
     // the match in obj.dict 

     ... 
    } 

を行うようにする方法では、私は今、私が提案されているものGetHashCodeメソッドをオーバーライドするだけでなく、する必要があり、別のインスタンスの辞書のものと辞書の各ペアの平等をチェックします。

辞書のすべてのキー、またはキーに値を加算する必要がありますか?

基本的には、次のようなことがうまくいくでしょうか。

public override int GetHashCode() 
{ 
    int iHash = 0; 

    foreach (KeyValuePair<string, T> pair in this.dict) 
    { 
     iHash ^= pair.Key.GetHashCode(); 
     iHash ^= pair.Value.GetHashCode(); 
    } 

    return iHash; 
} 
+2

http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overriden-in-c –

+0

http://stackoverflow.com/questions/1378686/general-advice-and-guidelines-on-how-to-override-object-gethashcode –

+0

ハッシュコードを生成しようとしていますか?これはあなたが作成したカスタムクラスですか?または、既存の辞書に何かのIEqualityComparerを渡していますか? –

答えて

0

オブジェクトをHashSetで使用する予定ですか?実際には、そのオブジェクトがそのハッシュによって一意に識別可能であるように使用される場合、GetHashCodeを実装する必要があります。 です。GetHashCodeは常に等価で使用されるフィールドと同じフィールドを考慮して実装することをお勧めしますが、必ずしもそうである必要はありません。

あなたのケースで必要な場合は、私はあなたが正しい考えを持っていると信じています。

+0

クール。それは私が知りたいことです。それは純粋に一意です。 – tom

+0

うれしい私は助けることができます。それがあなたにとって満足のいく回答であれば、答えとしてマークしていただければ幸いです。 :) –

1

@Mitch Wheatにリンクされていることに沿って、このクラスをDictionaryまたはHashSetで使用すると、GetHashCode()を実行する最善の方法ではありません。

内部ディクショナリには1つのエントリしかないとします。あなたのハッシュはその単一の値KeyValuePairの値になりました。クラス全体をHashSetに貼り付けます。あなたの内部に別のアイテムを追加するDictionary。あなたのクラスの2つのアイテムを反復処理しているので、クラスのハッシュコードが変更されました。

HashSet.Contains(obj)を呼び出すと、同じクラスインスタンスであっても変更されたobj.GetHashCode()が呼び出されます。 HashSet.Contains()はこの新しいハッシュを含んでおらず、falseを返し、決してEqualsを呼び出すことはない(参照が同じであれば真を返す)。

突然、あなたのオブジェクトはHashSetから消えました。たとえクラスがそこにあるとしても、古くなったハッシュです。

実際にハッシュを変更したくない場合は、 GetHashCodeに衝突しても問題ありません。衝突した場合、(遅い).Equals()メソッドが呼び出されるためです。これは便利な最適化であり、不適切に実装された場合、途中でいくつかの頭痛を引き起こす可能性があります。

上記のリンクで指摘したように、^の前に素数でハッシュを掛けて別の値を設定することをお勧めします。ユニークなものを保つのに役立ちます。

+0

これは有効な懸案事項です。もし辞書が不変であれば?あなたは上記の問題から解放されますか? – tom

+0

Key/Valueのペアが決して変更されない場合は、KeyValuePairが実際に追加されたり削除されたりすることなく、KeyValuePairの実際のキーと値が変更されないことを意味します。それについて心配する必要はありません。それぞれの 'KeyValuePair'の中で、キーまたは値はクラスであり、そのクラスは変更可能であり、変更された場合は別のHashCodeを出力します –