GetHashCode() overview

A hash code is a numeric value that is used to identify an object during equality testing, and it can also serve as an index for an object in a collection, such as a List, Dictionary or HashTable.

The problem is that the default .NET implementation of GetHashCode() does not guarantee unique values for different values, so you should override this method and provide your own implementation.

Some rules for implementing GetHashCode() are:

If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values.

The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state

For the best performance, a hash function must generate a random distribution for all input

Implementations of the GetHashCode method must not result in circular references (it can lead to a StackOverflowException).

Implementing GetHashCode()

I found a great post on StackOverflow on this topic. Jon Skeet has provided a good and simple implementation. Basically, you need to use prime numbers like 17, 23, 29, 31 in the hash code calculation. I decided to include also the type of the object in the calculation, because two objects with identical properties/values can return the same hash code.

Using T4 templates to generate GetHashCode()

T4 is a code generator built right into Visual Studio. You can generate any text file using T4 templates: C#, javascript, HTML, XML and many others. If you’ve never heard about it, this is a good place to start:

I don’t think that using a constant value as the initial value is the best choice, even if it is a prime number. As I already mentioned, two objects with identical properties/values can return the same hash code.

Reflection is not the best choice for hash code calculation:
1. Performance is worst;
2. Also, in many cases you don’t want to include all fields/properties of your object in the calculation (e.g., to avoid circular references). You would need extra code to know what fields/properties should be included or not in the hash code calculation.