2009-10-27 11 views
9

Ho una classe, mostra di seguito, che viene utilizzata come chiave in un Dictionary<ValuesAandB, string> Si verificano problemi durante il tentativo di trovare qualsiasi chiave all'interno di questo dizionario, non trova mai a tutti. Come puoi vedere, ho sostituito Equals e GetHashCode.Classe personalizzata utilizzata come chiave nel dizionario ma chiave non trovata

a cercare la chiave che sto utilizzando

ValuesAandB key = new ValuesAandB(A,B); 
if (DictionaryName.ContainsKey(key)) { 
    ... 
} 

C'è qualcos'altro che mi manca? Qualcuno può far notare cosa sto facendo male?

private class ValuesAandB { 
    public string valueA; 
    public string valueB; 

    // Constructor 
    public ValuesAandB (string valueAIn, string valueBIn) { 
    valueA = valueAIn; 
    valueB = ValueBIn; 
    } 

    public class EqualityComparer : IEqualityComparer<ValuesAandB> { 
     public bool Equals(ValuesAandB x, ValuesAandB y) { 
     return ((x.valueA.Equals(y.valueA)) && (x.valueB.Equals(y.valueB))); 
     } 
     public int GetHashCode(ValuesAandB x) { 
     return x.valueA.GetHashCode()^x.valueB.GetHashCode(); 
     } 
    } 
} 

E prima che qualcuno chieda, sì i valori sono nel dizionario!

risposta

9

Come stai costruendo il dizionario? Stai passando il tuo comparatore di uguaglianza personalizzato al suo costruttore?

6

Non hai sovrascritto uguale a e GetHashCode. Hai implementato una seconda classe che può fungere da EqualityCompeller. Se non si costruisce il dizionario con EqualityComparer, non verrà utilizzato.

La correzione più semplice sarebbe quella di ignorare GetHashCode e Uguale direttamente, piuttosto che l'attuazione di un operatore di confronto (comparatori sono generalmente interessanti solo quando è necessario fornire più tipi di confronto differenti (maiuscole e minuscole e maiuscole e minuscole, ad esempio) o quando è necessario essere in grado di eseguire confronti su una classe che non si controlla

+0

Sì, i commenti presi a bordo e la risposta corretta come si è scoperto, ma Greg Beech è arrivato prima che tu abbia paura. Grazie per l'aiuto però. –

1

Sembra che si stiano confrontando due stringhe.Iirc, quando si utilizza .Equals(), si sta confrontando il riferimento delle stringhe, non i contenuti effettivi Per implementare un EqualityComparer che funziona con le stringhe, si consiglia di utilizzare il metodo String.Compare()

public class EqualityComparer : IEqualityComparer<ValuesAandB> 
{ 
    public bool Equals(ValuesAandB x, ValuesAandB y) 
    { 
      return ((String.Compare(x.valueA,y.valueA) == 0) && 
      (String.Compare(x.valueB, y.valueB) == 0)); 
    } 
    // gethashcode stuff here 
} 

potrei essere un po 'fuori con il codice, che dovrebbe ottenere si chiude ...

+0

No, String.Equals (String) è il sovraccarico che verrà chiamato qui, che confronta in modo molto esplicito il contenuto. E in ogni caso, String.Equals (Object) viene sovrascritto per fare lo stesso. –

+0

* facepalm * Non sono sicuro di cosa stavo pensando. – cloggins

0

Ho avuto questo problema, risulta il dizionario stava confrontando referances per la mia chiave, non i valori nell'oggetto.

Stavo usando una classe Point personalizzata come chiavi. Ho scavalcato i metodi ToString() e GetHashCode() e viola, la ricerca della chiave ha funzionato bene.