-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
S3897 is an unsafe suggestion in my opinion #420
Comments
Hi @jabbera, Indeed we have seen your thread on Google Group but we haven't had the opportunity to have an internal discussion meeting on this subject. At first glance your suggestion make sense but we could also allow a virtual implementation of the equal. So we have to have a little talk to see whether we can think of a best solution. Cheers, |
Thanks for getting back to me! Glad to know it's being looked at. Cheers, |
Hi @jabbera! We have been discussing this subject with the team and we came up with the following solution:
We have decided to keep the rule as it is because it suggests you to implement Feel free to discuss the proposed solution if you thing we are missing something. |
Hi @Evangelink
Lets take the working example above and take the advice of S3897.
The second you introduce public type specific equals in a base class equality comparison breaks down when you compare classes derived from a common base class. IE: If the base class properties are equal the object will be considered equal even if they are not the same type. The origins of IEquatable are actually around structs and not class hierarchies. Before CLR 2.0 structs were compared using reflection. This was not only slow but required a ton of boxing\unboxing. See: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/struct I won't drag the topic on any more. If you still don't see the potential harm of this rule (or not having the new rule at the same severity level) feel free to close the issue. I'll be disabling the rule in my installation and be recommending the same to all of my users. Looking forward to working with you on more issues! Mike |
One last thing. I posted an issue on the roslyn-analysers and got the following from a MSFT employee:
|
Hi @jabbera! Thanks for your feedback that is really interesting and I wasn't aware of this tricky part. To have the example working I had to actually make We are also looking forward for more interactions with you (and more generally our community). |
Thanks for continuing to follow up. I wasn't aware of this either until I tracked down a rediculous production bug based on it. I've been scarred:-) |
Hi @jabbera , It took some time to get to a result. We have reduced the scope of S3897 to only suggest to implement I have created 2 tickets (one to fix the implementation #462 and one to implement the new rule #461) so I think I am safe closing this ticket. |
Agreed! Thanks for the update. |
I posted this in the google groups, but no one responded. Through I might get more traction here.
Hi all,
I wanted to discuss: S3897 (https://sonarcloud.io/organizations/default/rules#rule_key=csharpsquid%3AS3897)
I think it is an unsafe suggestion on it's surface if the class is not sealed. Especially as a major. The reason is fairly well described here: http://blog.mischel.com/2013/01/05/inheritance-and-iequatable-do-not-mix/
But the important quote: A class that implements IEquatable is saying, “I know how to compare two instances of type T or any type derived from T for equality.” After all, if type B derives from A, then B is-a A. That’s what inheritance means! The problem with implementing IEquatable on a non-sealed type is that a base class cannot know how to compare instances of derived types. Trying to implement IEquatable on a non-sealed class ends up producing inconsistent results when comparing instances of derived types.
Here is an example.
Those classes are obviously not equal but implementing the suggestion would make the runtime behave as such.
Thanks,
Mike
The text was updated successfully, but these errors were encountered: