I read in the Essential C# 3.0 and .NET 3.5 book that:
GetHashCode()’s returns over the life of a particular object should be constant (the same value), even if the object’s data changes. In many cases, you should cache the method return to enforce this.
Is this a valid guideline?
I have tried a couple built-in types in .NET and they didn’t behave like this.
The answer is mostly, it is a valid guideline, but perhaps not a valid rule. It also doesn’t tell the whole story.
The point being made is that for mutable types, you cannot base the hash code on the mutable data because two equal objects must return the same hash code and the hash code has to be valid for the lifetime of the object. If the hash code changes, you end up with an object that gets lost in a hashed collection because it no longer lives in the correct hash bin.
For example, object A returns hash of 1. So, it goes in bin 1 of the hash table. Then you change object A such that it returns a hash of 2. When a hash table goes looking for it, it looks in bin 2 and can’t find it – the object is orphaned in bin 1. This is why the hash code must not change
for the lifetime of the object, and just one reason why writing GetHashCode implementations is a pain in the butt.Update
Eric Lippert has posted a blog that gives excellent information on
GetHashCode.Additional Update
I’ve made a couple of changes above:
A guideline is just a guide, not a rule. In reality,
GetHashCodeonly has to follow these guidelines when things expect the object to follow the guidelines, such as when it is being stored in a hash table. If you never intend to use your objects in hash tables (or anything else that relies on the rules ofGetHashCode), your implementation doesn’t need to follow the guidelines.When you see ‘for the lifetime of the object’, you should read ‘for the time the object needs to co-operate with hash tables’ or similar. Like most things,
GetHashCodeis about knowing when to break the rules.