Search code examples
c#inheritance-prevention

Preventing methods from being inherited


I have a base class Foo that is concrete and contains 30 methods which are relevant to its subclasses.

Now I've come across a situation that is specific only to the base class,and I want to create a method that cannot be inherited, is this possible?

Class Foo 
{
   /* ... inheritable methods ... */

   /* non-inheritable method */
   public bool FooSpecificMethod()
   { 
      return true;
   } 
}

Class Bar : Foo
{
    /* Bar specific methods */
}

var bar = new Bar();
bar.FooSpecificMethod(); /* is there any way to get this to throw compiler error */

EDIT

I'm not sure if I was clear originally.

I do understand the principles of inheritance, and I understand the Liskov substitution principle. In this case there is a single exception that ONLY deals with the 'un-inherited' case, and so I did not want to create an 'uninheritedFoo' subclass.

I was asking if it is technically possible to create a situation where foo.FooSpecificMethod() is a valid and publicly accessible method, but subclassoffoo.FooSpecificMethod() throws a compiler error.

Essentially I want a sealed method on an unsealed class.


Solution

  • I would rethink the need for this.

    If you are using inheritance, you are suggesting that "Bar" IS A "Foo". If "Bar" is always a "Foo", methods that work on "Foo" should also work on "Bar".

    If this isn't the case, I would rework this as a private method. Publically, Bar should always be a Foo.


    Just to take this one step further -

    If you could do this, things would get very complicated. You could have situations where:

    Foo myBar = new Bar(); // This is legal
    myBar.FooSpecificMethod(); // What should this do?  
                               // It's declared a Foo, but is acutally a Bar
    

    You can actually force this behavior using reflection, though. I think it's a bad idea, but FooSpecificMethod() could check the type of this, and if it isn't typeof(Foo), throw an exception. This would be very confusing, and have a very bad smell.


    Edit in response to question's edit:

    There is no way for the compiler to enforce what you are asking. If you really want to force the compiler to check this, and prevent this, you really should consider making Foo a sealed class. You could use other extension methods than subclassing in this case.

    For example, you might want to consider using events or delegates to extend the behavior instead of allowing the object to be subclasses.

    Trying to do what you are accomplishing is basically trying to prevent the main goals of inheritance.