2009-10-30 21 views
9

Tengo un diccionario que estoy comparando con otro diccionario (variables escritas como IDictionary). Hacer d1.Equals (d2) produce falso. Escribir mi propio código a continuación es cierto. Ambos son System.Collections.Generic.Dictionary. ¿Me falta algo o Dictionary no tiene una implementación Equals que compara claves/valores?Does Dictionary.Equals() tiene una implementación?

private static bool DictEquals<K, V>(IDictionary<K, V> d1, IDictionary<K, V> d2) 
{ 
    if (d1.Count != d2.Count) 
     return false; 

    foreach (KeyValuePair<K, V> pair in d1) 
    { 
     if (!d2.ContainsKey(pair.Key)) 
      return false; 

     if (!Equals(d2[pair.Key], pair.Value)) 
      return false; 
    } 

    return true; 
} 

Respuesta

10

Dictionary.Equals() utiliza el valor predeterminado Equals from Object, verificando si los dos objetos son de la misma referencia, como lo hacen todas las demás colecciones predeterminadas. Eres libre de crear tu propia subclase con semántica de valores, aunque eso generalmente incluye que las cosas también sean inmutables.

+2

+1, como se dice en la documentación de la clase de diccionario. http://msdn.microsoft.com/en-us/library/3eayzh46.aspx. –

5

Probablemente el método de la clase Dictionary recurre Equals simplemente a la implementación predeterminada heredada de Object, es decir, que simplemente compara la referencia Dictionary objeto pasado con su propia referencia. Vea aquí: Object.Equals reference

1

Otros han mencionado que está utilizando la aplicación Object.equals, puede utilizar el siguiente para anularla:

public class EqualsDictionary<T, T> : Dictionary<T, T> 
{ 
    public override bool Equals(object obj) 
    { 
     //Place your comparison implementation here 
    } 
} 
+2

Para * anular * it, como dice la palabra clave. La sobrecarga es algo diferente. – Joren

+0

@Joren: Sí, todavía es demasiado temprano para mí. –

2

Suponiendo que dos diccionarios, uno de ellos un SortedList<TKey, TValue> y el otro un Dictionary<TKey, TValue>, se comparan para igualdad, ¿realmente debería volverse verdadero si los artículos son los mismos? Eso sería bastante malo, ya que tienen diferentes características y características (el SortedList<,>, por ejemplo, permite la recuperación a través del índice).

Además, la igualdad y el código hash están lógicamente unidos. El código hash debe ser inmutable, de lo contrario, todos los algoritmos basados ​​en hash no funcionarán. No puede garantizar esto cuando usa los contenidos para verificar la igualdad. Por lo tanto, la implementación predeterminada (verificando si son la misma instancia) es bastante sensata. Sin embargo, puedes crear tu propia comparación de igualdad de contenido.

+0

Punto justo, mi código anterior debería hacer la comprobación habitual de comparar identidad + clase antes de comparar el contenido. –

+0

Derecha. Sin embargo, esto todavía no sería un reemplazo adecuado para Igual() debido al problema del código hash: si dos objetos son iguales, su código hash debe ser igual, y el código hash debe ser inmutable. En consecuencia, Equals() puede no ser verdadero solo porque dos colecciones son del mismo tipo con los mismos contenidos, porque todavía tendrán un hashcode diferente (inmutable, lo siento como para estresarlo). – Lucero

+0

@Lucero: Es una lástima que.NET solo define un conjunto de métodos virtuales de relación de equivalencia, ya que la mayoría de los tipos de clases "inmutables" contienen referencias a objetos que serían mutables *, excepto que las referencias nunca se expondrán a nada que pueda mutarlas * y sería útil si hubiera eran métodos estándar que las clases de envoltura inmutables podrían usar para comprimir o verificar la igualdad en sus contenidos. – supercat

0

Las referencias en .NET se pueden usar para encapsular la identidad de un objeto, los aspectos mutables de su estado, ambos o ninguno, además de encapsular aspectos inmutables del estado de un objeto. En general, si no existe una razón particular para suponer lo contrario, .NET supone que las referencias a objetos mutables se utilizan con el fin de encapsular la identidad. Además, asume que, en los casos en que el código compara referencias sin saber qué representan, es mejor equivocarse al informar cosas desiguales. Como tal, dos referencias a objetos mutables generalmente se consideran equivalentes si y solo si identifican el mismo objeto, por lo que no se recomienda que los tipos mutables anulen el Equals para indicar algo más. En cambio, el código que usa referencias para encapsular el estado mutable debe usar algún medio que no sea Object.Equals() para compararlos.

Cuestiones relacionadas