Modify rule S4039: Improve description to match the implementation (#4586)

This commit is contained in:
Sebastien Marichal 2024-12-23 14:57:36 +01:00 committed by GitHub
parent bb47c97c62
commit 07d614dd5b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,14 +1,22 @@
== Why is this an issue?
When a base type explicitly implements a public interface method, that method is only accessible in derived types through a reference to the current instance (namely ``++this++``). If the derived type explicitly overrides that interface method, the base implementation becomes inaccessible.
When a base type explicitly implements a public interface method, property or event, that member is only accessible in derived types through a reference to the current instance (namely `this`). If the derived type explicitly overrides that interface member, the base implementation becomes inaccessible.
This rule raises an issue when an unsealed, externally visible type provides an explicit member implementation of an `interface` and does not provide an alternate, externally visible member with the same name.
This rule raises an issue when an unsealed, externally visible type provides an explicit method implementation of a ``++public interface++`` and does not provide an alternate, externally visible method with the same name.
=== Exceptions
This rule does not report a violation for an explicit implementation of `IDisposable.Dispose` when an externally visible `Close()` or `System.IDisposable.Dispose(Boolean)` method is provided.
=== Noncompliant code example
== How to fix it
[source,csharp]
Make the class sealed, change the class member to a non-explicit declaration, or provide a new class member exposing the functionality of the explicit interface member.
=== Code examples
==== Noncompliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public interface IMyInterface
{
@ -21,27 +29,13 @@ public class Foo : IMyInterface
{
MyMethod();
}
void MyMethod()
{
// Do something ...
}
}
public class Bar : Foo, IMyInterface
{
public void MyMethod()
{
// Can't access base.MyMethod()
// ((IMyInterface)this).MyMethod() would be a recursive call
}
}
----
=== Compliant solution
==== Compliant solution
[source,csharp]
[source,csharp,diff-id=1,diff-type=compliant]
----
public interface IMyInterface
{
@ -55,26 +49,19 @@ public class Foo : IMyInterface
MyMethod();
}
protected void MyMethod() // or public
// This method can be public or protected
protected void MyMethod()
{
// Do something ...
}
}
public class Bar : Foo, IMyInterface
{
public void MyMethod()
{
// Do something
base.MyMethod();
}
}
----
== Resources
=== Exceptions
=== Documentation
This rule does not report a violation for an explicit implementation of ``++IDisposable.Dispose++`` when an externally visible ``++Close()++`` or ``++System.IDisposable.Dispose(Boolean)++`` method is provided.
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation[Explicit Interface Implementation]
ifdef::env-github,rspecator-view[]