This is one of those topics that all developers use nearly every day without being often aware of. Now it’s quite rare that you need to deal with hash code and override Equals. The more you do object modeling (and domain modeling) the more you need it.
The .NET Framework strongly recommends that whenever you override Equals you also override GetHashCode. But why is it so?
Method Equals is always used when equality is checked explicitly such as when your code calls Equals directly or uses the == operator. GetHashCode is not involved in the equality assessment process. Subsequently, its implementation doesn’t impact the equality evaluation. Yet, you get a compiler warning if you override Equals but not GetHashCode.
GetHashCode comes into play only if your objects are going to be stored within hash tables or used as dictionary keys. In this case, the .NET Framework uses the value returned by GetHashCode to find the corresponding entry in the hash table or dictionary. Two object instances that are the same object according to Equals but return different values according to GetHashCode will never be considered equal. As a result, different values will be picked from the hash table or dictionary.
When your objects appear as public objects in a class library, you simply have no guarantee that they will never be used within hash tables or as dictionary keys. For this reason, it is strongly recommended that you override both methods to ensure that two objects that are equal according to Equals also return the same GetHashCode value. The returned value doesn’t matter as long as it’s the same. In light of this, why not simply making GetHashCode return a constant value in all cases?
When GetHashCode returns the same value for two objects you get a collision and Equals is called to ensure the objects are the same. A performance goal is of course minimizing the number of collisions giving each object with a unique combination of values a different hash code.
Finally, note that the hash code should never change during the lifetime of an object. For this to happen, only immutable properties should be used to calculate the code. This fits perfectly with guidelines for entities and value objects.