2012-01-06 11 views
5

¿Las llaves de un Dictionary deben ser comparables con la igualdad?Requisito de igualdad del diccionario C#

Por ejemplo

Class mytype 
{ 
    public bool equals(mytype other) 
    { 
     return ...; 
    } 
} 

En mi caso no serán iguales a menos que sean la misma instancia.

Si necesito implementar la igualdad, ¿debo tener un gran valor numérico que se incremente con cada nueva instancia de mytype creada?

Respuesta

3

Si sus clases son solo equal si son la misma instancia, entonces no necesita hacer nada para usarlas en un Dictionary. Las clases (tipos de referencia) se consideran iguales si y solo si se refieren al mismo objeto.

From the documentation of GetHashCode

Para las clases derivadas de objeto, el método GetHashCode puede delegar a la aplicación Object.GetHashCode, si y sólo si esa clase derivada define la igualdad de valor a ser la igualdad de referencia y el tipo no es un tipo de valor .

Lo que parece ser cierto en su caso. Como regla general, si anula Igual, debe anular GetHashCode, pero esto no es necesario en su caso, ya que lo predeterminado es lo que está buscando.

+0

Gracias, una buena respuesta. – alan2here

1

De forma predeterminada, la igualdad se basa en la instancia. Dos instancias separadas nunca son iguales. Solo puede cambiar eso al proporcionar su propio método Equals.

+1

También querrá implementar 'GetHashCode()' –

0

No, no hay restricciones de tipo de Dictionary<TKey, TValue>

2

Sólo si están siendo utilizados como una llave y que no quieren la equivalencia de base en la instancia del objeto en sí. Si solo quiere que las referencias a la misma instancia sean equivalentes, está bien y no necesita hacer nada, pero si usa su tipo como clave y desea que las instancias "equivalentes" se consideren iguales, su clase debe implementar Equals() y GetHashCode().

Si su tipo personalizado se almacena como un valor, y no se utiliza como una clave, esto no es necesario, por supuesto. Por ejemplo, en este caso MyType no necesita anular Equals() o GetHashCode() porque solo se usa como un valor y no como la clave de almacenamiento.

Dictionary<string, MyType> x; 

Sin embargo, en este caso:

Dictionary<MyType, string> x; 

su tipo personalizado es la clave, y por lo tanto tendría que anular Equals() y GetHashCode(). El GetHashCode() se usa para determinar a qué ubicación se asigna, y el Equals() se usa para resolver colisiones en el código hash (entre otras cosas).

Debería anular los mismos dos métodos al tratar con muchas consultas LINQ también. Alternativamente, puede proporcionar un IEqualityComparer autónomo aparte de su clase para determinar si dos instancias son equivalentes.

+0

Pero si la igualdad de referencia es el comportamiento deseado, el tipo no debe anular estos métodos, y el OP parece indicar que la igualdad de referencia * es * el comportamiento deseado. – phoog

+0

@phoog: buena pregunta, su afirmación "En mi caso no serán iguales a menos que sean la misma instancia" para mí puede leerse de cualquier manera como "esto es lo que está haciendo" o "esto es lo que quiero" hacer ", actualicé mi respuesta para reflejar de cualquier manera. –

0

Ver la propiedad EqualityComparer.Default<T>.Así es como el diccionario obtiene un comparador de igualdad si no lo proporciona con uno.

Esto devuelve un comparador de igualdad en función del tipo & capacidades de T.

Por ejemplo, si T se extiende IEquatable, EqualityComparer.Default volverán una instancia comparador de igualdad que utiliza la interfaz IEquatable. De lo contrario, devolverá una instancia de comparación de igualdad que utiliza el método Object.Equals.

El método Object.Equals, de forma predeterminada para los tipos de referencia, usa igualdad de referencia (Object.ReferenceEquals) a menos que lo anule con una comparación personalizada.

El método Object.Equals, de forma predeterminada para los tipos de valor, utiliza la reflexión para comparar los campos de la estructura para la igualdad *. La reflexión es lenta, por eso siempre se recomienda anular Igual en tipos de valor.

* a menos que sea un tipo de valor blittable en cuyo caso se comparan los bits sin procesar.