¿Qué devolver cuando se invalida Object.GetHashCode () en clases sin campos inmutables?

Ok, antes de que te enojes porque hay cientos de preguntas similares que se publican en Internet, puedo asegurarte que acabo de pasar las últimas horas leyendotodos ellos y no he encontrado la respuesta a mi pregunta.

Fondo:

Básicamente, una de mis aplicaciones a gran escala había estado sufriendo una situación en la que algunosBindings en elListBox.SelectedItem la propiedad dejaría de funcionar o el programa se bloquearía después de haber realizado una edición en el elemento seleccionado actualmente. Inicialmente pregunté'Ya se ha agregado un elemento con la misma clave' Excepción al seleccionar un elemento ListBoxItem del código Pregunta aquí, pero no tengo respuestas.

No había tenido tiempo de abordar ese problema hasta esta semana, cuando me dieron varios días para resolverlo. Ahora para resumir una larga historia, descubrí la razón del problema. Fue porque mis clases de tipo de datos habían anulado elEquals método y por lo tanto elGetHashCode método también.

Ahora, para aquellos de ustedes que desconocen este problema, descubrí que solo pueden implementar elGetHashCode método usandoinmutable campos / propiedades Usando un extracto de la respuesta de Harvey Kwok a laAnulando GetHashCode () Publicar para explicar esto:

El problema es que GetHashCode está siendo utilizado por las colecciones Dictionary y HashSet para colocar cada elemento en un contenedor. Si el código de hash se calcula en función de algunos campos mutables y los campos se cambian realmente después de colocar el objeto en el HashSet o el Diccionario, el objeto ya no se puede encontrar en el HashSet o el Diccionario.

Entonces elreal El problema fue causado porque había usadomudable propiedades en elGetHashCode metodos Cuando los usuarios modificaron estos valores de propiedad en la interfaz de usuario, los valores de código hash asociados de los objetos cambiaron y luego los artículos ya no se podían encontrar en sus colecciones.

Pregunta:

Entonces, mi pregunta es cuál es la mejor manera de manejar la situación en la que necesito implementar elGetHashCode ¿Método en clases sin campos inmutables? Lo siento, déjame ser más específico, comoese preguntatiene ha preguntado antes

Las respuestas en elAnulando GetHashCode () post sugiere que en estas situaciones, es mejor simplemente devolver un valor constante ... algunos sugieren devolver el valor1, mientras que otros sugieren devolver un número primo. Personalmente, no puedo ver ninguna diferencia entre estas sugerencias porque pensé que solo se usaría una cubeta para cualquiera de ellas.

Además, elPautas y reglas para GetHashCode El artículo en el blog de Eric Lippert tiene una sección tituladaPauta: la distribución de códigos hash debe ser "aleatoria" lo que resalta los inconvenientes de usar un algoritmo que hace que no se usen suficientes cubos. Advierte de algoritmos quedisminuye el número de cubetas utilizadas y causa un problema de rendimiento cuando la cubeta se vuelve realmente grande. Seguramente, devolver una constante cae en esta categoría.

Tuve la idea de añadir un extraGuid campo a todas mis clases de tipo de datos (solo en C #, no en la base de datos) específicamente para ser usado en y solo en elGetHashCode método. Así que supongo que al final de esta larga introducción, mireal ¿Qué pregunta es qué implementación es mejor? Resumir:

Resumen:

Al anular Object.GetHashCode () en clases sin campos inmutables, ¿es mejor devolver una constante desde elGetHashCode método, o para crear un adicionalreadonly campo para cada clase, únicamente para ser utilizado en elGetHashCode ¿método? Si debo agregar un nuevo campo, ¿qué tipo debería ser y no debería incluirlo en elEquals ¿método?

Si bien estoy feliz de recibir respuestas de cualquier persona, realmente espero recibir respuestas de desarrolladores avanzados con un buen conocimiento sobre este tema.

Respuestas a la pregunta(4)

Su respuesta a la pregunta