views:

130

answers:

3

Often, in C# documentation, you come across a member where the description says something along the lines of "be sure to call the base method if you override this."

Is there a way to ensure at compile time that one has actually called the base function?

Here's an example: Implementing a Dispose Method

From the first lines:

A type's Dispose method should release all the resources that it owns. It should also release all resources owned by its base types by calling its parent type's Dispose method.

EDIT

I was browsing, and I came across this article, which seems rather relevant. It's more of a small than an error, ie. it has valid uses (such as those mentioned):

Call Super

+7  A: 

You can't enforce it, but you can do it via a call like base.Foo(bar). base allows you to access members of the class you're inheriting from.

You can kind of enforce this behavior by using the template method pattern. For example, imagine you had this code:

abstract class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("I'm an animal.");
    }
}

class Dog : Animal
{
    public override void Speak()
    {
        base.Speak();
        Console.WriteLine("I'm a dog.");
    }
}

The trouble here is that any class inheriting from Animal needs to call base.Speak(); to ensure the base behavior is executed. You can automatically enforce this by taking the following (slightly different) approach:

abstract class Animal
{
    public void Speak()
    {
        Console.WriteLine("I'm an animal.");
        DoSpeak();
    }

    protected abstract void DoSpeak();
}

class Dog : Animal
{
    protected override void DoSpeak()
    {
        Console.WriteLine("I'm a dog.");
    }
}

In this case, clients still only see the polymorphic Speak method, but the Animal.Speak behavior is guaranteed to execute. The problem is that if you have further inheritence (e.g. class Dachsund : Dog), you have to create yet another abstract method if you want Dog.Speak to be guaranteed to execute.

Chris Schmich
Jon actually posted the template method pattern solution first. Sorry, didn't mean to step on toes.
Chris Schmich
@Chris: No problem - you've given a more concrete example. I'll ditch my answer.
Jon Skeet
Thanks, I'll accept this answer. Others have mentioned it as well, but this is a good summary that includes the important caveats
Carlos
That was tricky thanks
Mubashar Ahmad
+5  A: 

You can call it like this:

public override void MyFunction()
{
    // do dome stuff
    SomeStuff();

   // call the base implementation
   base.MyFunction();
}

But if you're asking whether it can be "checked" at compile time - no.

You could probably use a dependency analysis tool such as NDepend to create rules to check this is being done, and have the rules run as part of the compile, but I don't think you can do the enforecement from the compiler itself.

Rob Levine
A: 

A common pattern for a single level of inheritance is to provide a non-virtual template method with a virtual extension point.

protected virtual void ExtensionPoint () { }

public void TemplateMethod () {
    ExtensionPoint();
    ThisWillAlwaysGetCalled();
}

If all calls to the operation call the template method, then any override of the extension point will be called, along with the code in the template method which will always get called.

Pete Kirkham