C# Language Writing a good GetHashCode override


Example

GetHashCode 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 a List, Dictionary, or similar.

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.