Modify rule S4019: LaYC format (#2141)
This commit is contained in:
parent
63488517d8
commit
5e048dd441
@ -24,5 +24,5 @@
|
||||
"defaultQualityProfiles": [
|
||||
"Sonar way"
|
||||
],
|
||||
"quickfix": "unknown"
|
||||
"quickfix": "infeasible"
|
||||
}
|
||||
|
@ -1,63 +1,73 @@
|
||||
== Why is this an issue?
|
||||
|
||||
When a method in a derived class has the same name as a method in the base class but with a signature that only differs by types that are weakly derived (e.g. ``++object++`` vs ``++string++``), the result is that the base method becomes hidden.
|
||||
When a method in a derived class has:
|
||||
|
||||
* the same name as a method in the base class
|
||||
* but types of parameters that are ancestors (for example `string` in the base class and `object` in the derived class)
|
||||
|
||||
=== Noncompliant code example
|
||||
the result is that the base method becomes hidden.
|
||||
|
||||
[source,csharp]
|
||||
As shown in the following code snippet, when an instance of the derived class is used, invoking the method with an argument that matches the less derived parameter type will invoke the derived class method instead of the base class method:
|
||||
|
||||
[source,csharp,diff-id=1,diff-type=noncompliant]
|
||||
----
|
||||
using System;
|
||||
|
||||
namespace MyLibrary
|
||||
class BaseClass
|
||||
{
|
||||
class Foo
|
||||
{
|
||||
internal void SomeMethod(string s1, string s2) { }
|
||||
}
|
||||
|
||||
class Bar : Foo
|
||||
{
|
||||
internal void SomeMethod(string s1, object o2) { } // Noncompliant
|
||||
}
|
||||
internal void MyMethod(string str) => Console.WriteLine("BaseClass: Method(string)");
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
=== Compliant solution
|
||||
|
||||
[source,csharp]
|
||||
----
|
||||
using System;
|
||||
|
||||
namespace MyLibrary
|
||||
class DerivedClass : BaseClass
|
||||
{
|
||||
class Foo
|
||||
{
|
||||
internal void SomeMethod(string s1, string s2) { }
|
||||
}
|
||||
|
||||
class Bar : Foo
|
||||
{
|
||||
internal void SomeOtherMethod(string s1, object o2) { }
|
||||
}
|
||||
internal void MyMethod(object str) => Console.WriteLine("DerivedClass: Method(object)"); // Noncompliant
|
||||
}
|
||||
|
||||
// ...
|
||||
BaseClass baseObj = new BaseClass();
|
||||
baseObj.MyMethod("Hello"); // Output: BaseClass: Method(string)
|
||||
|
||||
DerivedClass derivedObj = new DerivedClass();
|
||||
derivedObj.MyMethod("Hello"); // Output: DerivedClass: Method(object) - DerivedClass method is hiding the BaseClass method
|
||||
|
||||
BaseClass derivedAsBase = new DerivedClass();
|
||||
derivedAsBase.MyMethod("Hello"); // Output: BaseClass: Method(string)
|
||||
----
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
[source,csharp,diff-id=1,diff-type=compliant]
|
||||
----
|
||||
class BaseClass
|
||||
{
|
||||
internal void MyMethod(string str) => Console.WriteLine("BaseClass: Method(string)");
|
||||
}
|
||||
|
||||
'''
|
||||
== Implementation Specification
|
||||
(visible only on this page)
|
||||
class DerivedClass : BaseClass
|
||||
{
|
||||
internal void MyOtherMethod(object str) => Console.WriteLine("DerivedClass: Method(object)"); // Compliant
|
||||
}
|
||||
|
||||
=== Message
|
||||
// ...
|
||||
BaseClass baseObj = new BaseClass();
|
||||
baseObj.MyMethod("Hello"); // Output: BaseClass: Method(string)
|
||||
|
||||
Remove or rename that method because it hides '{base.method}'.
|
||||
DerivedClass derivedObj = new DerivedClass();
|
||||
derivedObj.MyMethod("Hello"); // Output: BaseClass: Method(string)
|
||||
|
||||
BaseClass derivedAsBase = new DerivedClass();
|
||||
derivedAsBase.MyMethod("Hello"); // Output: BaseClass: Method(string)
|
||||
----
|
||||
|
||||
=== Highlighting
|
||||
Keep in mind that you cannot fix this issue by using the https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier[new keyword] or by marking the method in the base class as `virtual` and overriding it in the `DerivedClass` because the parameter types are different.
|
||||
|
||||
Method declaration
|
||||
=== Exceptions
|
||||
|
||||
The rule is not raised when the two methods have the same parameter types.
|
||||
|
||||
endif::env-github,rspecator-view[]
|
||||
== Resources
|
||||
|
||||
=== Documentation
|
||||
|
||||
* https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords[Knowing When to Use Override and New Keywords]
|
||||
* https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/member-overloading[Member overloading]
|
||||
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier['new' modifier]
|
||||
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0108[CS0108 - Hiding inherited member]
|
||||
|
||||
include::../rspecator.adoc[]
|
15
rules/S4019/rspecator.adoc
Normal file
15
rules/S4019/rspecator.adoc
Normal file
@ -0,0 +1,15 @@
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
== Implementation Specification
|
||||
(visible only on this page)
|
||||
|
||||
=== Message
|
||||
|
||||
Remove or rename that method because it hides '{base.method}'.
|
||||
|
||||
=== Highlighting
|
||||
|
||||
Method declaration
|
||||
|
||||
endif::env-github,rspecator-view[]
|
Loading…
x
Reference in New Issue
Block a user