I apologize for the shortness of the title, but the actual title would be a bit too long. Here is the actual long title:
Equals()
without GetHashCode()
but no warning when overriding GetHashCode()
without Equals()
?I also apologize in advance about the fact that this is not a "What is the X of Y" type of question, it is more of an "I observed X; am I missing something?" type of question.
So, consider the following:
class A
{
public override bool Equals( object other ) => true; //warning CS0659
}
class B
{
public override int GetHashCode() => 42; //No warning
}
I am aware of the reasons behind warning CS0659 "class overrides Object.Equals(object o) but does not override Object.GetHashCode()". I do not agree with those reasons, because Equals()
is perfectly viable for a mutable class, whereas such a class must of course never be used as a key in a hash map, and therefore must not have a GetHashCode()
, but my objections are irrelevant, and in any case, receiving a warning which you have no need for is never a problem, because you can always disable it.
It is, however, a problem when you can think of a warning that you would have a use for, but you are not receiving such a warning.
This is what class B
above demonstrates. Overriding GetHashCode()
without also overriding Equals()
is almost certainly a grave mistake, and yet there is no warning. Not by the C# compiler, nor by ReSharper.
Does anyone know why?
Is there something I am missing?
Could it be that the warning exists, but I must know some configuration magic to tease it out of the compiler?
Could it be that I must declare my class in some weird way like public
sealed
albino
or something?
Are there any legitimate reasons for the absence of the warning?
EDIT
So far there have been a few answers to this question and they all pretty much state the same thing: there is no warning because there is no violation of the contract for GetHashCode()
and Equals()
.
Ladies and gentlemen, you are missing the point.
(Or maybe I should say I apologize for failing to make the point more clear.)
The "no violation of contract" argument in support of the absence of this warning makes about as much sense as trying to support the absence of some other warning, like "event is never used", on the grounds that by declaring an event and never using it you are not violating any contract either.
Well, first of all, if I was violating some contract by declaring an event and never using it, I would expect an error, not a warning.
But most importantly, declaring an event and never using it is a grave and insidious mistake, so it needs a warning, regardless of contracts.
It is CS0067 "The event '{0}' is never used".
See? warnings do not require any contracts to be violated.
So that argument is blown out of the water.
Any other arguments, please?
The GetHashCode() method should reflect the Equals
logic; the rules are:
Equals(...) == true
) then they must return the same value for GetHashCode()
GetHashCode()
is equal, it is not necessary for them to be the same; this is a collision, and Equals
will be called to see if it is a real equality or not.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With