org.sonar.plugins.csharp.S4015.html Maven / Gradle / Ivy
Why is this an issue?
Decreasing the accessibility
level of an inherited method that is not overridable to private will shadow the name of the base method and can
lead to confusion.
public class Base
{
public void SomeMethod(int count) { }
}
public class Derived : Base
{
private void SomeMethod(int count) { } // Noncompliant
}
class Program
{
public void DoWork()
{
var derived = new Derived();
derived.SomeMethod(42); // Base.SomeMethod is accessed here
}
}
Another potential problem is the case of a class deriving from Derived
and accessing SomeMethod
. In this scenario, the
method accessed will instead be the Base
implementation, which might not be what was expected.
public class Base
{
public void SomeMethod(int count) { }
}
public class Derived : Base
{
private void SomeMethod(int count) { } // Noncompliant
}
public class SecondDerived : Derived
{
public void DoWork()
{
SomeMethod(42); // Base.SomeMethod is accessed here
}
}
One way to mitigate this, is by sealing the Derived
class by using the sealed modifier, thus preventing inheritance from this
point on.
public class Base
{
public void SomeMethod(int count) { }
}
public sealed class Derived : Base
{
private void SomeMethod(int count) { } // Compliant: class is marked as sealed
}
Another way to mitigate this, is by having the Derived
implementation match the accessibility modifier of the
Base
implementation of SomeMethod
. From a caller’s perspective, this is closer to the expected behavior.
using System;
namespace MyLibrary
{
public class Base
{
public void SomeMethod(int count) { }
}
public class Derived : Base
{
public void SomeMethod(int count) { } // Compliant: same accessibility as Base.SomeMethod
}
public class Program
{
public void DoWork()
{
var derived = new Derived();
derived.SomeMethod(42); // Derived.SomeMethod is called
}
}
}
Last but not least, consider using a different name for the Derived
method, thus completely eliminating any confusion caused by the
naming collision.
public class Base
{
public void SomeMethod(int count) { }
}
public class Derived : Base
{
private void SomeOtherMethod(int count) { } // Compliant
}
Resources
Documentation