Si usted no está anulando GetHashCode
que acaba de heredar Object.GetHashCode
. Object.GetHashCode
básicamente devuelve la dirección de memoria de la instancia, si se trata de un objeto de referencia. Por supuesto, cada vez que se carga un objeto, es probable que se cargue en una parte diferente de la memoria y, por lo tanto, se obtenga un código hash diferente.
Es discutible si eso es lo correcto; pero eso es lo que se implementó "de vuelta en el día", por lo que no puede cambiar ahora.
Si desea algo consistente, debe sobrescribir GetHashCode
y crear un código basado en el "valor" del objeto (es decir, las propiedades y/o campos). Esto puede ser tan simple como una fusión distribuida de los códigos hash de todas las propiedades/campos. O bien, podría ser tan complicado como lo necesites. Si todo lo que está buscando es algo para diferenciar dos objetos diferentes, entonces puede ser útil usar una clave única en el objeto. Si está buscando el seguimiento de cambios, usar la clave única para el hash probablemente no va a funcionar
Simplemente uso todos los códigos hash de los campos para crear un código hash razonablemente distribuido para el objeto primario. Por ejemplo:
public override int GetHashCode()
{
unchecked
{
int result = (Name != null ? Name.GetHashCode() : 0);
result = (result*397)^(Street != null ? Street.GetHashCode() : 0);
result = (result*397)^Age;
return result;
}
}
El uso del número primo 397 es generar un número único para un valor de distribuir mejor el código hash. Consulte http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/ para obtener más detalles sobre el uso de números primos en los cálculos del código hash.
Podría, por supuesto, usar el reflejo para obtener todas las propiedades para hacer esto, pero sería más lento. Alternativamente, puede usar el CodeDOM para generar código dinámicamente para generar el hash basado en la reflexión sobre las propiedades y la caché de ese código (es decir, generarlo una vez y volverlo a cargar la próxima vez). Pero, por supuesto, esto es muy complejo y puede no valer la pena el esfuerzo.
Un hash MD5 o SHA o CRC generalmente se basa en un bloque de datos. Si quieres eso, entonces usar el código hash de cada propiedad no tiene sentido. Posiblemente serializar los datos en la memoria y calcular el hash de esa manera sería más aplicable, como lo describe Henk.
¿Los hash se almacenan entre sesiones? –
Más información sobre cómo serializar deserializar estos objetos. ¿Y está sobrescribiendo GetHashCode()? – Paparazzi