Search code examples
c#inheritanceparent-childderived-classaccess-levels

can we define a method in parent class which can be called within a child but not the other one


i ran into into a problem , i want to have a method(M) in a parent class (A) then B and C extend the class A . in this situation i want method(M) can be accessible by B but not C . any solution?

public class A
{
    ????? string M()
    {
        return "Hi there";
    }
}
public class B:A
{
}
public class C:A
{
}
B newClassB = new B();
C newClassC = new C();
Console.WriteLine(newClassB.M()); //the correct one
Console.WriteLine(newClassC.M()); //the incorrect one

Solution

  • Ok, a useful answer (my previous one was not).

    No, you can't and you shouldn't do this, due to the Liskov Substitution Principle already pointed out in other answers and comments.

    However, there are cases where it can be justified, and as a matter of fact, some classes in NET do implement the following pattern:

    public class A
    {
        public virtual bool CanCallM => true;
        public void M() {
            if (!CanCallM) throw new NotSupportedException();
            //do whatever }
    }
    
    public class B: A { }
    
    public class C: A
    {
        public override bool CanCallM => false;
    }
    

    Pretty? Not much, but you do give the consumer a way to know beforehand if M can be called, and you are ensuring at runtime that c.M fails.

    I personally prefer this pattern to simply doing nothing because the later is probably a bug in the code; someone is calling M with an expectation that is not met.