If you ever had to implement the Equals()
method to compare two instances of a type in .NET, you had to implement the GetHashCode()
method too.
The GetHashCode
method returns a numeric value which is used to identify an object during equality testing. It can also serve as an index for an object in a collection. The purpose of the method is to create a key for hashtable.
It is by design useful for only one thing: putting an object in a hash table.
It is faster to use the return value of GetHashCode
to determine whether two objects are equal than to call the default implementation of Equals
on the object type.
In other words, GetHashCode
is used to generate a unique identifier for an object that can be used to compare it with other objects. It is used internally by the .NET framework for quick comparisons.
If you had to implement the GetHashCode method, there were some rules that should be followed which could make it quite a challenge to implement it correctly:
- Equal items have equal hashes
- The integer returned by
GetHashCode
must never change while the object is contained in a data structure that depends on the hash code remaining stable GetHashCode
must never throw an exception, and must returnGetHashCode
must be performant
To follow all those rules we had a lot of magic going one. Here is an example from one of our applications:
We see the usage of the unchecked
keyword to gain some extra performance by stopping overflow checks, magic numbers like 5 and 397. Most of the developers just copy this code without any clue why we are doing this.
Starting from .NET Core 2.1, we can leave all this magic to the framework itself and use the built-in HashCode struct:
No more magic!
Remark: If you are still working with pre .NET Core 2.1 code, you can use the Microsoft.Bcl.HashCode
NuGet package.
More information
Guidelines and rules for GetHashCode | Fabulous adventures in coding (ericlippert.com)
Object.GetHashCode Method (System) | Microsoft Learn