Writing a good GetHashCode override
suggest changeGetHashCode
has major performance effects on Dictionary<> and HashTable.
Good GetHashCode
Methods
- should have an even distribution
- every integer should have a roughly equal chance of returning for a random instance
- if your method returns the same integer (e.g. the constant ‘999’) for each instance, you’ll have bad performance
- should be quick
- These are NOT cryptographic hashes, where slowness is a feature
- the slower your hash function, the slower your dictionary
- must return the same HashCode on two instances that
Equals
evaluates to true- if they do not (e.g. because
GetHashCode
returns a random number), items may not be found in aList
,Dictionary
, or similar.
- if they do not (e.g. because
A good method to implement GetHashCode
is to use one prime number as a starting value, and add the hashcodes of the fields of the type multiplied by other prime numbers to that:
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 3049; // Start value (prime number).
// Suitable nullity checks etc, of course :)
hash = hash * 5039 + field1.GetHashCode();
hash = hash * 883 + field2.GetHashCode();
hash = hash * 9719 + field3.GetHashCode();
return hash;
}
}
Only the fields which are used in the Equals
-method should be used for the hash function.
If you have a need to treat the same type in different ways for Dictionary/HashTables, you can use IEqualityComparer.
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents