C Overriding the GetHashCode method
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In C#, you override GetHashCode when your type defines value-based equality and you want hash-based collections such as Dictionary and HashSet to behave correctly. The rule is strict: if two objects are equal according to Equals, they must return the same hash code.
GetHashCode and Equals are a pair
A hash code is not a unique identifier. It is a compact value used to place objects into hash buckets efficiently. Collisions are allowed. What is not allowed is this:
- '
x.Equals(y)istrue' - but
x.GetHashCode()andy.GetHashCode()are different
That breaks the assumptions used by hash-based collections.
So if you override GetHashCode, you usually also override Equals.
A simple value-object example
This is the common modern pattern: compare the same fields in Equals that you combine in GetHashCode.
Use immutable fields whenever possible
Hash-based collections assume that the hash code of an object does not change while the object is being used as a key. That is why immutable fields are strongly preferred in equality and hash-code logic.
If you base the hash on mutable properties and then change one of them after inserting the object into a HashSet or Dictionary, lookups may stop working as expected.
That is one of the most common real-world bugs in custom hash-code implementations.
HashCode.Combine is the easiest modern approach
Older C# code often used manual prime multiplication patterns. That still works, but HashCode.Combine is usually clearer and less error-prone.
Manual approach:
Modern approach:
The important thing is consistency with Equals, not nostalgia for a manual formula.
Do not optimize for uniqueness
A good hash code should distribute values reasonably, but it is not required to be unique. Two unequal objects may share the same hash code. Collections handle collisions internally.
That means you should not overengineer the method trying to eliminate all collisions. Focus on correctness and reasonable distribution.
Records already solve much of this
If your type is a simple value-like data carrier, a C# record often generates the equality and hashing behavior you want automatically.
That is often better than manually overriding both methods on a trivial value object.
Common Pitfalls
- Overriding
GetHashCodewithout also makingEqualsconsistent. - Including mutable fields in the hash code for objects used as dictionary keys.
- Assuming hash codes must be unique for unequal objects.
- Recomputing hash from fields that are not part of logical equality.
- Writing elaborate custom hash formulas when
HashCode.Combineor a record would be simpler.
Summary
- Override
GetHashCodewhen your type has value-based equality. - Keep
GetHashCodeconsistent withEquals. - Prefer immutable fields for values used in hashing.
- '
HashCode.Combineis the normal modern implementation tool.' - For simple value objects, consider using records instead of manual overrides.

