visual studio c# .net dictionary gethashcode

c# - studio - ¿Debo reemplazar GetHashCode() en los tipos de referencia?



override equals c# (3)

Leí la mayoría de las preguntas en StackOverflow con respecto a GetHashCode . Pero todavía no estoy seguro de si debo anular GetHashCode en los tipos de referencia. Recogí lo siguiente de la respuesta de alguien en otra pregunta:

Object.GetHashCode () usa un campo interno en la clase System.Object para generar el valor de hash. A cada objeto creado se le asigna una clave de objeto única, almacenada como un entero, cuando se crea. Estas teclas comienzan en 1 y se incrementan cada vez que se crea un nuevo objeto de cualquier tipo.

Si esto sigue siendo cierto en .NET Framework 3.5 (¿alguien puede confirmarlo?), Entonces el único problema que veo con las implementaciones predeterminadas de los tipos de referencia es que el código hash tendrá una distribución deficiente.

Voy a romper mis preguntas:

a) ¿Por lo tanto, se recomienda anular GetHashCode si se usa en un Dictionary o si la implementación predeterminada funciona bien?

b) Tengo tipos de referencia en los que sería fácil hacerlo ya que tienen campos que los identifican de forma única, pero ¿qué pasa con los tipos de referencia en los que todos los miembros también son tipos de referencia? ¿Qué debo hacer ahí?


Acabo de hacer una prueba de muestra, y no veo cómo comienza en 1 y se incrementa.

for (int i = 0; i < 16; i++) { object obj = new object(); Console.Write(obj.GetHashCode() + " "); }

con estos resultados:

45653674 41149443 39785641 45523402 35287174 44419000 52697953 22597652 10261382 59109011 42659827 40644060 17043416 28756230 18961937 47980820

De hecho, usando Reflector, solo pude ver esto:

internal static extern int InternalGetHashCode(object obj);

Entonces, ¿cómo sucede realmente? Es un misterio para mí (puede haber un patrón, pero no voy a profundizar en este punto, ¿quizás algún tipo de algorithm "número pseudoaleatorio"?). Alguien del equipo CLR podría responder eso.

En cuanto a las otras preguntas, Reed en realidad me venció con el golpe re: GetHashCode and Equals . La page MSDN lo describe con algunos detalles más sangrientos, por si acaso.



Solo necesita anular GetHashCode () en los tipos de referencia si anula Object.Equals ().

El motivo es simple: normalmente, 2 referencias siempre serán distintas (a.Equals (b) == false, a menos que sean el mismo objeto). La implementación predeterminada de GetHashCode () proporcionará 2 hashes distintos en este caso, por lo que todo es bueno.

Sin embargo, si reemplaza a Equals (), este comportamiento no está garantizado. Si dos objetos son iguales (según Equals ()), debe garantizar que tendrán el mismo código hash con GetHashCode, por lo que debe anularlo.