2012-04-04 1 views
12

私は、リストをキーとされた辞書があります。私はにContainsKeyを使用しようとしているが、それは動作していないようです、と私は理由は分からないC#一覧キー

private Dictionary<List<custom_obj>, string> Lookup; 

を。ここで は私のVisual Studioのイミディエイトウィンドウからデバッグ情報です:私の常識で

?Lookup.Keys.ElementAt(7)[0] 
{custom_obj} 
    Direction: Down 
    SID: 2540 
?Lookup.Keys.ElementAt(7)[1] 
{custom_obj} 
    Direction: Down 
    SID: 2550 
searchObject[0] 
{custom_obj} 
    Direction: Down 
    SID: 2540 
searchObject[1] 
{custom_obj} 
    Direction: Down 
    SID: 2550 
?Lookup.ContainsKey(searchObject) 
false 

、その最後にContainsKeyは真でなければなりません。うまくいけば私はここに十分な情報を含んでいます...どんなアイデアですか?

ありがとうございます!

答えて

14

キーとして機能するList<custom_obj>インスタンスは、searchObjectによって参照されるインスタンスとは一意に等しくありません。

一致するキーを検索するために、参照の等価性の代わりにリストの値を使用する場合は、辞書のconstructorにIEqualityComparerを指定する必要があります(List<T>でEqualsとGetHashCodeをオーバーライドできないためです)。

3

これは、ルックアップで使用される実際のリストインスタンスが、キーとして追加されたインスタンスと同じ場合にのみ機能します。リストの内容は比較されません。これは、2つのListオブジェクトを直接比較しようとする場合と同じ動作です。

8

同じ要素を含む2つの別個のListがあります。 2つのリストが等しいかどうかを調べる正しい方法は、SequenceEqualメソッドです。

デフォルトでは、実行しようとしていることを行うことはできません。しかし、カスタムIEqualityComparerを書いてDictionaryコンストラクタに渡すことができます。ここで

はサンプルジェネリックIEqualityComparerです:

class ListComparer<T> : IEqualityComparer<List<T>> 
{ 
    public bool Equals(List<T> x, List<T> y) 
    { 
     return x.SequenceEqual(y); 
    } 

    public int GetHashCode(List<T> obj) 
    { 
     int hashcode = 0; 
     foreach (T t in obj) 
     { 
      hashcode ^= t.GetHashCode(); 
     } 
     return hashcode; 
    } 
} 

これは間に合わせと-ソリューションだったとしてあなたは、GetHashCode実装に改善することをお勧めします。

+0

GetHashCodeには返品がありません。 –

+0

クイックノート:答えがヒントとして、あなたはこのComparerを使用すべきではありません。 equalsメソッドは順序に敏感ですが、ハッシュメソッドは順序に影響されません。 –

0

ルックアップメソッドで使用しているインスタンスが、辞書のキーに含まれるインスタンスと同じインスタンスであることは確かですか?それが私が考えることができる唯一のものです。