I'm implementing IEquatable<T>
, and I am having difficulty finding consensus on the GetHashCode
override on a mutable class.
The following resources all provide an implementation where GetHashCode
would return different values during the object's lifetime if the object changes:
- https://mcmap.net/q/32890/-is-there-a-complete-iequatable-implementation-reference
- https://csharp.2000things.com/tag/iequatable/
- http://broadcast.oreilly.com/2010/09/understanding-c-equality-iequa.html
However, this link states that GetHashCode
should not be implemented for mutable types for the reason that it could cause undesirable behaviour if the object is part of a collection (and this has always been my understanding also).
Interestingly, the MSDN example implements the GetHashCode
using only immutable properties which is in line with my understanding. But I'm confused as to why the other resources don't cover this. Are they simply wrong?
And if a type has no immutable properties at all, the compiler warns that GetHashCode
is missing when I override Equals(object)
. In this case, should I implement it and just call base.GetHashCode()
or just disable the compiler warning, or have I missed something and GetHashCode
should always be overridden and implemented? In fact, if the advice is that GetHashCode
should not be implemented for mutable types, why bother implementing for immutable types? Is it simply to reduce collisions compared to the default GetHashCode
implementation, or does it actually add more tangible functionality?
To summarise my Question, my dilemma is that using GetHashCode
on mutable objects means it can return different values during the lifetime of the object if properties on it change. But not using it means that the benefit of comparing objects that might be equivalent is lost because it will always return a unique value and thus collections will always fall back to using Equals
for its operations.
Having typed this Question out, another Question popped up in the 'Similar Questions' box that seems to address the same topic. The answer there seems to be quite explicit in that only immutable properties should be used in a GetHashCode
implementation. If there are none, then simply don't write one. Dictionary<TKey, TValue>
will still function correctly albeit not at O(1) performance.
GetHashCode
must use immutable properties only. Otherwise, use the default one, which as per the last paragraph in my Question, would still allow aDictionary<TKey, TValue>
to function correctly, but without the O(1) performance it would normally have. – TismanGetHashCode()
your dictionary will not function correctly. See this example – EyespotGetHashCode
. How would you implementGetHashCode
in this example? – Tisman