No necesita implementarlo. Si escribe su propio método Equals(), le recomendaría utilizar alguna implementación de GetHashCode que no rompa el HashSet. Por ejemplo, podría devolver un valor estático (generalmente 42). El rendimiento de HashSet se reducirá drásticamente, pero al menos funcionará; nunca sabrá quién usará/editará/mantendrá su código en el futuro. (Edit: es posible que desee registrar una advertencia si dicha clase se utiliza en una estructura de hash con el fin de los primeros problemas de rendimiento spot)
EDIT: no sólo el uso XOR para combinar códigos hash de sus propiedades
Ya han dicho otros que simplemente puede combinar los códigos hash de todas sus propiedades. Sin embargo, en lugar de solo usar XOR, animo a multiplicar los resultados. XOR puede dar como resultado un valor de 0 si ambos valores son iguales (por ejemplo, 0xA^0xA == 0x0
). Esto se puede mejorar fácilmente usando 0xA * 0xA
, 0xA * 31 + 0xA
o 0xA^(0xA * 31)
.
Aún así, la intención de mi respuesta es que cualquier función hash es mejor que una que no es consistente con iguales, incluso si solo devuelve un valor estático. Simplemente seleccione cualquier subconjunto de propiedades (de ninguna a todas) que use para igualdad y arroje los resultados juntos. Al seleccionar propiedades para código hash, prefiera esos subconjuntos pequeños cuyas combinaciones son bastante únicas (por ejemplo, nombre, apellido, fecha de nacimiento - no es necesario agregar toda la dirección)
Eche un vistazo a Essential C# 4.0 (o anterior si ya tiene) en el capítulo 9 * Tipos bien formados * y sabrá cuándo anularlo. – Oliver