tags:

views:

52

answers:

5

I have a base class and a class inheriting base. The base class has several virtual functions that the inherited class may override. However, the virtual functions in the base class has code that MUST to run before the inherited class overrides get called. Is there some way that I can call the base classes virtual functions first then the inherited class overrides. Without making a call to base.function().

I know I can simply make two functions, one that gets called, the other virtual. But is there a way I can keep the same names as well? I know I may need to change some things around.

class myBase
{
    public virtual myFunction()
        { /* must-run code, Called first */ }
}

class myInherited : myBase
{
    public override myFunction()
        { /* don't use base.myFunction();,
        called from base.myFunction(); */ }
}

Similar question here.

+6  A: 

A common solution that can be found in the .NET Framework is to split a method in a public method XXX and a protected, virtual method OnXXX that is called by the public method. For your example, it would look like this:

class MyBase
{
    public void MyMethod()
    {
        // do something
        OnMyMethod();
        // do something
    }

    protected virtual void OnMyMethod()
    {
    }
}

and

class MyInherited : MyBase
{
    protected override void OnMyMethod()
    {
        // do something
    }
}
dtb
Is there a way I can do this without making two functions in the base class? or at the very least make them have the same name?
Dave
@Dave: No, there is no way to magically call an overridden base method before or after the virtual method call. You have to split it in some way. (If you split it, you can also enforce that an overriding method calls the overridden base method, in addition to doing something before and after the protected method.)
dtb
+2  A: 

C# doesn't have support for automatically enforcing this, but you can enforce it 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
A: 

There is no way to do what you're seeking other than the 2 ways you already named.

Either you make 2 functions in the base class, one that gets called and the other virtual.

Or you call base.functionName in the sub-class.

Steve Michelotti
A: 

Not exactly. But I've done something similar using abstract methods.

Abstract methods must be overriden by derived classes. Abstract procs are virtual so you can be sure that when the base class calls them the derived class's version is called. Then have your base class's "Must Run Code" call the abstract proc after running. voila, your base class's code always runs first (make sure the base class proc is no longer virtual) followed by your derived class's code.

class myBase
{
    public /* virtual */ myFunction()  // remove virtual as we always want base class's function called here 
    { /* must-run code, Called first */ 

        // call derived object's code
        myDerivedMustcallFunction();    
    }

    public abstract myDerivedMustCallFunction() { /* abstract functions are blank */ }
}

class myInherited : myBase
{
    public override myDerivedMustCallFunction()
    { /* code to be run in derived class here */ }
}
Zippit
A: 

What do you think of this?

class myBase
{
    public void myFunctionWrapper()
    {
        // do stuff that must happen first
        // then call overridden function
        this.myFunction();
    }

    public virtual void  myFunction(){ 
       // default implementation that can be overriden

    }

}

class myInherited : myBase
{
    public override void myFunction()
    { 

    }
}
Jaap