2012-06-06 15 views
7

Tengo un objeto CustomObject que anula GetHashCode(). Tengo un HashSet, y puedo llamar a agregar con dos objetos distintos que tienen el mismo código hash. Ambos se agregan y más tarde termino con algunos problemas de inserción de base de datos (duplicados de clave primaria) ... El propósito de usar un hashSet se conectó a estas inserciones de base de datos (evitando colisiones de clave).¿Por qué C# hashSet acepta agregar dos objetos con el mismo valor de getHashCode()?

¿Me estoy perdiendo algunas propiedades de HashSet? Incluso cuando intento verificar (.Contains) antes de agregar (.Add), termino agregando hashCode duplicados ...

+2

Si una colisión hash fuera suficiente para que el HashSet considerara dos valores duplicados, sería bastante inútil. Hashes idénticos para valores desiguales son de esperar. – delnan

+0

Bueno, el hash perfecto es un concepto que podría tener sentido – Jerome

Respuesta

22

Porque la membresía HashSet<T> se basa en igualdad de objeto, no en igualdad de código hash. Es perfectamente legal que cada miembro de un HashSet<T> tenga el mismo código hash siempre que los miembros sean diferentes según Equals. El rol que juegan los códigos hash en HashSet<T> es para realizar pruebas rápidas de membresía. Si tiene un objeto y su código hash no está en el HashSet<T>, entonces sabe que el objeto no está en el HashSet<T>. Si tiene un objeto y su código hash está en el HashSet<T>, entonces tiene que recorrer la cadena de objetos con el mismo código hash para probar la igualdad usando Equals para ver si el objeto está realmente en el HashSet<T> o no. Es por eso que una distribución equilibrada del código hash es importante. Pero no es el caso que sean necesarios códigos hash únicos.

+0

Está mal decir que hashset se basa en la igualdad, porque se basa tanto en la igualdad como en el código hash. En primer lugar, se calcula un hash para elegir una dirección precisa, y luego equals se usa para colocar el elemento en la lista de colisiones. –

+3

Estás hablando de un detalle de implementación. HashSet es un conjunto, y la membresía está determinada por Igual igualdad. Simplemente sucede que usa código hash para el rendimiento. Lee mi respuesta, y ya te indiqué el mecanismo que describes. Por favor, elimine el voto abajo. – jason

1

Do no utilice hashsets para intentar evitar valores duplicados. Úselos para equilibrar tablas hash!

+0

Esto no responde la pregunta de por qué se permiten hashes duplicados. –

+0

¿Eh? Los conjuntos son una buena opción para filtrar duplicados. A menos que * haya * una diferencia que no se refleje en el hash y la igualdad y cuide qué objeto se retiene, pero eso parece bastante raro. No sé mucho sobre el mundo .NET, ¿quizás extraño algo? – delnan

+0

@ChrisShain, delnan Seré honesto, pensé que había agregado esto como un comentario y lo había notado. – asawyer

8

Reemplazar GetHashCode no es suficiente. También debe sobrescribir la función Equals.

+0

¿Por qué se rechaza esta votación? – GianT971

+1

¿Por qué se bajó este voto? Tal vez no sea la respuesta * completa *, pero es un punto seguro para comenzar. Así que me ajusté con +1. –

Cuestiones relacionadas