The reason those are warnings rather than errors is that the code will still work (probably), but it might do things that you don't expect. The warning is a big red flag that says, "Hey! You might be doing something bad here. You might want to take another look at it."
As it turns out, the warning is right on.
In this particular case, it's possible that some code can call Object.Equals(object)
on one of your BaseId
objects. For example, somebody could write:
bool CompareThings(BaseId thing, object other)
{
return thing.Equals(other);
}
The compiler will generate a call to Object.Equals(object)
because your BaseId
type doesn't override it. That method will do the default comparison, which is the same as Object.ReferenceEquals(object)
. So you have two different meanings of Equals
. You need to override Object.Equals(object)
and have it call Equals(BaseId)
after checking that the object being compared is indeed of type BaseId
.
In the second case, you're right: there probably isn't a need to override GetHashCode
, since the object doesn't define any new fields or do anything that changes the meaning of Equals. But the compiler doesn't know that. Sure, it knows that you didn't add any fields, but you did override Equals
, meaning that you potentially changed the meaning of equality. And if you changed the meaning of equality, then you very likely changed (or should change) how hash codes are computed.
Not handling equality properly is a very common cause of mistakes when designing new types. It's a good thing that the compiler is overly cautious in this area.