2012-04-04 17 views
12

Ho un dizionario che viene digitato da un elenco:C# List come dizionario chiave

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

Sto cercando di usare ContainsKey, ma non sembra funzionare, e non ho idea del perché . Ecco le informazioni di debug dal mio Visual Studio finestra immediata:

?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 

Nel mio buon senso, che lo scorso ContainsKey dovrebbe essere vero. Spero di aver incluso abbastanza informazioni qui ... qualche idea?

Grazie!

risposta

14

L'istanza List<custom_obj> che funge da chiave è referenzialmente diseguale rispetto all'istanza indicata da searchObject.

Se si desidera che il dizionario di utilizzare i valori nella lista, invece di uguaglianza referenziale per trovare chiavi corrispondenti, è necessario fornire un IEqualityComparer nel constructor del dizionario (dal momento che non è possibile ignorare Equals e GetHashCode in List<T>).

3

Questo funziona solo se l'istanza dell'elenco reale utilizzata nella ricerca è uguale all'istanza aggiunta come chiave. Non confronterà i contenuti della lista. Questo è lo stesso comportamento che si ottiene se si tenta di confrontare direttamente due oggetti List.

8

Si dispone di due separati List s che contengono gli stessi elementi. Il modo corretto per scoprire se due liste sono uguali è con il metodo SequenceEqual.

Come impostazione predefinita, non è possibile eseguire ciò che si sta tentando di eseguire. È comunque possibile scrivere un numero personalizzato IEqualityComparer e passarlo nel costruttore Dictionary.

Ecco un esempio generico 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; 
    } 
} 

Si consiglia di migliorare la GetHashCode realizzazione, in quanto questa era una soluzione rapida e-sporco.

+0

GetHashCode manca un ritorno. –

+0

Nota rapida: come suggerisce la risposta, non utilizzare questo Comparatore. Il metodo equals è sensibile all'ordine ma il metodo hash non lo è. –

0

Sei sicuro che l'istanza che stai utilizzando nel tuo metodo di ricerca è la stessa istanza che si trova tra le chiavi del tuo dizionario? Questa è l'unica cosa che riesco a pensare.

Problemi correlati