Implementing GetHashCode correctly
Data Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.
Ensuring that `GetHashCode` is implemented correctly is essential for maintaining the efficiency and correctness of hash-based collections like `Dictionary`, `HashSet`, and others in .NET. A hash code is an integer that is used by hash-based collections to quickly locate a bucket where objects with the same hash code are organized.
The Basics of GetHashCode
In .NET, each object has a method `GetHashCode()` derived from the `System.Object` class, which provides a default implementation. However, for custom objects, using the default implementation might not be ideal, particularly if the objects are stored in a hash-based collection. Implementing it correctly can significantly affect both performance and correctness.
Principles of Implementing GetHashCode
- Consistency: The hash code for an object should not change while the object is stored in a collection. This requires that the properties contributing to the hash code remain immutable or treated as such.
- Equal Objects Must Have Equal `Hash` Codes: If two objects are considered equal (`Equals` method returns `true`), then their hash codes must be the same. The converse is not true—two different objects can have the same hash code.
- Efficiency: The `GetHashCode` function should be fast, as it might be called frequently when using hash-based collections.
- Distribution: It should provide a good distribution of hash codes to minimize collisions. A collision occurs when different inputs produce the same hash code.
Sample Implementation
Here's a simple example of implementing `GetHashCode` for a custom object:
- Mutability: The properties `FirstName`, `LastName`, and `DateOfBirth` are read-only after the object is constructed, preventing unintentional changes.
- Null Handling: The `null` conditional operator (`?.`) and null-coalescing operator (`??`) are used to safely compute hash codes for possibly `null` strings.
- Unchecking for Overflow: The `unchecked` block allows integer overflow without throwing an exception, wrapping around as needed, which is acceptable for hash codes.
Related reading
- Implementing IDisposable correctly
- Implementing INotifyPropertyChanged - does a better way exist?
- Implementing MVC with Windows Forms
- implicit vs explicit interface implementation
- In ASP.NET, when should I use Session.Clear rather than Session.Abandon?
- In c 5.0, does async/await function always run on main thread at the beginning of running
- In c convert anonymous type into key/value array?
- In C, how to check if a TCP port is available?

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseData Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.