2009-10-27 11 views
9

Mam klasę, pokaż poniżej, która jest używana jako klucz w Dictionary<ValuesAandB, string> Mam problemy podczas próby znalezienia dowolnego klucza w tym słowniku, nigdy nie znajdzie to w ogóle. Jak widać, nadpisałem Equals i GetHashCode.Klasa niestandardowa używana jako klucz w słowniku, ale klucz nie został znaleziony

Aby szukać klucza używam

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

Czy jest coś innego, co mi brakuje? Czy ktoś może wskazać, co robię źle?

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

I zanim ktokolwiek zapyta, tak, wartości są w Słowniku!

Odpowiedz

9

W jaki sposób konstruujesz słownik? Czy przekazujesz swój niestandardowy porównywalnik równości do swojego konstruktora?

6

Nie zastąpiłeś Equals i GetHashCode. Zaimplementowano drugą klasę, która może służyć jako EqualityComparer. Jeśli nie skonstruujesz Słownika przy użyciu EqualityComparer, nie zostanie on użyty.

Najprostszą poprawką byłoby zastąpienie GetHashCode i Equals bezpośrednio, zamiast implementowania porównywalnika (porównawcy są na ogół interesujący tylko wtedy, gdy trzeba podać wiele różnych typów porównania (na przykład wielkość liter i wielkość liter nie ma znaczenia) lub kiedy trzeba możliwość wykonywania porównań w klasie, której nie kontrolujesz:

+0

Tak, komentarze na pokładzie i poprawna odpowiedź, jak się okazało, ale Greg Beech wyprzedził cię. Dzięki za pomoc. –

1

Wygląda na to, że porównujesz dwa ciągi.Iirc, podczas korzystania z .Equals(), porównujesz referencje łańcuchów, a nie rzeczywistą zawartość Aby zaimplementować EqualityComparer, który działa z łańcuchami, należy użyć metody 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 
} 

Mogę być trochę z kodem, który powinien cię zamknąć ...

+0

Nie, String.Equals (String) to przeciążenie, które zostanie wywołane tutaj, które bardzo wyraźnie porównuje zawartość. W każdym przypadku String.Equals (Object) jest nadpisywane, aby zrobić to samo. –

+0

* facepalm * Nie jestem pewien, co myślałem. – cloggins

0

Miałem ten problem, okazało się, że słownik porównuje referances dla mojego klucza, a nie wartości w obiekcie.

Używam niestandardowej klasy Punkt jako klawiszy. Przełamałem metody ToString() i GetHashCode() oraz altówkę, a wyszukiwanie klucza działało dobrze.

Powiązane problemy