2009-10-27 31 views
9

J'ai une classe, montre ci-dessous, qui est utilisé comme une clé dans un Dictionary<ValuesAandB, string> Je rencontre des problèmes lorsque je cherche une clé dans ce dictionnaire, elle ne trouve jamais du tout. Comme vous pouvez le voir, j'ai remplacé Equals et GetHashCode.Personnalisé Classe utilisée comme clé dans le dictionnaire mais clé non trouvée

Pour chercher la clef J'utilise

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

Y at-il autre chose que je suis absent? Quelqu'un peut-il signaler ce que je fais mal?

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(); 
     } 
    } 
} 

Et avant que quelqu'un ne demande, oui les valeurs sont dans le dictionnaire!

Répondre

9

Comment construisez-vous le dictionnaire? Transmettez-vous votre comparateur d'égalité personnalisé à son constructeur?

6

Vous n'avez pas remplacé Equals et GetHashCode. Vous avez implémenté une seconde classe qui peut servir de EqualityComparer. Si vous ne construisez pas le dictionnaire avec EqualityComparer, il ne sera pas utilisé. La solution la plus simple consiste à remplacer directement GetHashCode et Equals plutôt que d'implémenter un comparateur (les comparateurs ne sont généralement intéressants que lorsque vous devez fournir plusieurs types de comparaison différents (sensible à la casse et à la casse, par exemple) ou lorsque vous devez capable d'effectuer des comparaisons sur une classe que vous ne contrôlez pas

+0

Oui, les commentaires ont été pris à bord et la bonne réponse a été donnée, mais Greg Beech est arrivé devant vous, j'ai peur. Merci pour l'aide cependant. –

1

Il semble que vous comparez deux chaînes: Iirc, lorsque vous utilisez .Equals(), vous comparez la référence des chaînes, pas le contenu réel . pour mettre en œuvre un EqualityComparer qui fonctionne avec des chaînes, vous voulez utiliser la méthode 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 
} 

Je pourrais être un peu hors avec le code, qui devrait vous fermer ...

+0

Non, String.Equals (String) est la surcharge qui sera appelée ici, qui compare très explicitement le contenu. Et dans tous les cas, String.Equals (Object) est substitué pour faire la même chose. –

+0

* facepalm * Je ne suis pas sûr de ce que je pensais. – cloggins

0

J'ai eu ce problème, s'avère que le dictionnaire comparait des références pour ma clé, pas les valeurs dans l'objet. J'utilisais une classe Point personnalisée en tant que clés. J'ai outrepassé les méthodes ToString() et GetHashCode() et l'alto, la recherche de clé fonctionnait bien.