2012-04-04 15 views
12

Ich habe ein Wörterbuch, das von einer Liste eingegeben wird:C# Liste als Wörterbuch Schlüssel

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

Ich versuche ContainsKey zu verwenden, aber es scheint nicht zu arbeiten, und ich habe keine Ahnung, warum . Hier ist die Debug-Informationen von meinem Visual Studio Direkt-Fenster:

?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 

In meinem gesunden Menschenverstand, dass letzte ContainsKey wahr sein sollte. Hoffentlich habe ich genug Informationen hier ... irgendwelche Ideen?

Danke!

Antwort

14

Die List<custom_obj> Instanz, die als Schlüssel fungiert, ist in Bezug auf die Instanz, auf die searchObject verweist, ungleichmäßig.

Wenn Sie das Wörterbuch wollen die Werte in der Liste zu verwenden, anstatt von Referenz Gleichheit passende Schlüssel zu finden, müssen Sie einen IEqualityComparer im constructor des Wörterbuchs liefern (da Sie nicht Equals und GetHashCode in List<T> außer Kraft setzen können).

3

Dies funktioniert nur, wenn die tatsächliche Listeninstanz, die in der Suche verwendet wird, mit der Instanz übereinstimmt, die als Schlüssel hinzugefügt wurde. Es wird nicht den Listeninhalt vergleichen. Dies ist das gleiche Verhalten, das Sie erhalten, wenn Sie versuchen, zwei List-Objekte direkt miteinander zu vergleichen.

8

Sie haben zwei separate List s, die dieselben Elemente enthalten. Der richtige Weg, um herauszufinden, ob zwei Listen gleich sind, ist die SequenceEqual Methode.

Sie können nicht standardmäßig tun, was Sie versuchen zu tun. Sie können jedoch eine benutzerdefinierte IEqualityComparer schreiben und sie in den Dictionary Konstruktor übergeben.

Hier ist ein Beispiel generic 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; 
    } 
} 

Möglicherweise möchten Sie auf der GetHashCode Umsetzung verbessern, da dies eine schnelle und unsaubere Lösung war.

+0

GetHashCode fehlt eine Rückgabe. –

+0

Kurzanleitung: Wie die Antwort darauf hinweist, sollten Sie diesen Comparer nicht verwenden. Die equals-Methode ist für die Reihenfolge empfindlich, die Hash-Methode dagegen nicht. –

0

Sind Sie sicher, dass die Instanz, die Sie in Ihrer Suchmethode verwenden, dieselbe Instanz ist, die zu den Schlüsseln Ihres Wörterbuchs gehört? Das ist das Einzige, was mir einfällt.

Verwandte Themen