After symmetry, another aspect of the equality contract is
.GetHashCode(). When you first override
.Equals(object), the C# compiler will helpfully remind you that you must also override
Well, it’s not so helpful really, it’s a compiler error - you don’t get a choice about whether to implement it or not.
The relationship between
.Equals(object) is perhaps best demonstrated with some code:
Note particularly that these rules don’t reverse - having the same hash code doesn’t make two things equal, and being unequal doesn’t require different hash codes.
See if you spot the subtle bug in the following semantic type …
Don’t worry, I’m not going to make you wait until my next post to find the answer.
But I do want to put in a bit of a gap so that you don’t accidentally see the answer before you’re ready.
Here’s a hint. Given the context of our current discussion, you know it has to relate to an inconsistency
Consider this example code - what would it output to the console?
You might expect it to output
false, but it doesn’t.
It actual writes
The hash codes for
beta are different, even though
.Equals() says they are the equal. How can this be?
The implementation of
Equals() is case insensitive (so “foo” and “Foo” are considered equal), but the implementation of
GetHashCode() is case sensitive - it cares about letter case and gives a different value for each identifier.
Fortunately, the folks behind the .NET Framework have already solved this problem and the required fix is already present and ready for use. Here’s a conforming implementation of
Assuming you have good unit test coverage of
Equals() that covers all of the edge cases, you can catch this kind of error by exercising
GetHashCode() with the same test data - consider these tests:
A correct implementation of
GetHashCode() can be tricky if you don’t take the time to think it through. Unfortunately, a minor bug here can lead to subtle bugs in your production system where it won’t simply fail, but will instead do the wrong thing some of the time. And those are the some of the worst bugs to track down.