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
}