2009-10-27 21 views
9

Tengo una clase, mostrar a continuación, que se utiliza como clave en un Dictionary<ValuesAandB, string> Tengo problemas al intentar encontrar cualquier clave dentro de este diccionario, nunca encuentra en absoluto. Como puede ver, he anulado Equals y GetHashCode.Clase personalizada utilizada como clave en el diccionario pero no se encontró la clave

Para buscar la llave que estoy usando

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

¿Hay algo más que me falta? ¿Alguien puede señalar lo que estoy haciendo 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(); 
     } 
    } 
} 

Y antes de que nadie pregunte, sí, ¡los valores están en el Diccionario!

Respuesta

9

¿Cómo está construyendo el diccionario? ¿Está pasando su comparador de igualdad personalizado a su constructor?

6

No ha reemplazado Equals y GetHashCode. Ha implementado una segunda clase que puede servir como EqualityComparer. Si no construye el Diccionario con el EqualityComparer, no se usará.

La solución más simple sería anular GetHashCode e Igual directamente en lugar de implementar un comparador (los comparadores generalmente solo son interesantes cuando necesita proporcionar múltiples tipos de comparación diferentes (distingue entre mayúsculas y minúsculas, por ejemplo) o cuando necesita capaz de realizar comparaciones en una clase que no controla.

+0

Sí, los comentarios realizados a bordo y la respuesta correcta como resultado, pero Greg Beech se metió delante de ti, me temo. Gracias por la ayuda sin embargo. –

1

Parece que está comparando dos cadenas. Iirc, cuando usa .Equals(), está comparando la referencia de las cadenas, no los contenidos reales Para implementar un EqualityComparer que funcione con cadenas, querrá utilizar el método 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 
} 

Podría estar un poco apagado con el código, eso debería acercarlo ...

+0

No, String.Equals (String) es la sobrecarga que se llamará aquí, que compara de forma muy explícita los contenidos. Y en cualquier caso, String.Equals (Object) se reemplaza para hacer lo mismo. –

+0

* facepalm * No estoy seguro de lo que estaba pensando. – cloggins

0

Tuve este problema, resulta que el diccionario estaba comparando los referendos para mi clave, no los valores en el objeto.

Estaba usando una clase Point personalizada como llaves. Sobreescribí los métodos ToString() y GetHashCode() y viola, la búsqueda de teclas funcionó bien.

Cuestiones relacionadas