开发者

Call base function then inherited function

开发者 https://www.devze.com 2023-01-16 15:25 出处:网络
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

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.


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 inheritance (e.g. class Dachshund : Dog), you have to create yet another abstract method if you want Dog.Speak to be guaranteed to execute.


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
    }
}


 public abstract class BaseTemp
{
    public void printBase() {
        Console.WriteLine("base");
        print();
    }

    public abstract void print();

}

public class TempA: BaseTemp
{
    public override void print()
    {
        Console.WriteLine("TempA");
    }
}

public class TempB: BaseTemp
{
    public override void print()
    {
        Console.WriteLine("TempB");
    }
}


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.


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 */ }
}


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()
    { 

    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消