C# 调用基函数,然后调用继承的函数

C# 调用基函数,然后调用继承的函数,c#,inheritance,C#,Inheritance,我有一个基类和一个继承基类的类。基类有几个继承类可以重写的虚拟函数。但是,基类中的虚拟函数具有必须在调用继承的类重写之前运行的代码。是否有某种方法可以先调用基类虚函数,然后调用继承的类重写。不调用base.function() 我知道我可以简单地创建两个函数,一个被调用,另一个虚拟。但是有没有办法让我也保留相同的名字?我知道我可能需要改变一些事情 class myBase { public virtual myFunction() { /* must-run code,

我有一个基类和一个继承基类的类。基类有几个继承类可以重写的虚拟函数。但是,基类中的虚拟函数具有必须在调用继承的类重写之前运行的代码。是否有某种方法可以先调用基类虚函数,然后调用继承的类重写。不调用base.function()

我知道我可以简单地创建两个函数,一个被调用,另一个虚拟。但是有没有办法让我也保留相同的名字?我知道我可能需要改变一些事情

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(); */ }
}

类似的问题。

在.NET Framework中可以找到一个常见的解决方案,就是将公共方法中的方法
XXX
和受保护的、由公共方法调用的虚拟方法
OnXXX
。对于您的示例,它将如下所示:

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

    protected virtual void OnMyMethod()
    {
    }
}

C#不支持自动强制执行,但是 您可以使用。例如,假设您有以下代码:

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.");
    }
}
这里的问题是从
Animal
继承的任何类都需要调用
base.Speak()以确保执行基本行为。您可以通过采取以下(略有不同)方法自动强制执行此操作:

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.");
    }
}

在这种情况下,客户端仍然只能看到多态的
Speak
方法,但是
Animal.Speak
行为保证执行。问题是,如果您有进一步的继承(例如,
class Dachshund:Dog
),如果您想保证执行
Dog.Speak
,就必须创建另一个抽象方法。

除了您已经命名的两种方法之外,没有其他方法可以完成您正在寻找的任务

要么在基类中创建两个函数,一个被调用,另一个为虚拟函数


或者在子类中调用base.functionName。

不完全正确。但我用抽象的方法做过类似的事情

抽象方法必须由派生类重写。抽象过程是虚拟的,因此可以确保当基类调用它们时,派生类的版本被调用。然后让基类的“必须运行代码”在运行后调用抽象过程。瞧,基类的代码总是先运行(确保基类进程不再是虚拟的),然后是派生类的代码

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

你觉得这个怎么样

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

    }
}

有没有一种方法可以做到这一点,而不必在基类中生成两个函数?或者至少让它们具有相同的名称?@Dave:不,没有办法在虚拟方法调用之前或之后神奇地调用重写的基方法。你必须以某种方式把它分开。(如果拆分它,除了在受保护的方法之前和之后执行某些操作外,还可以强制重写方法调用被重写的基方法。)这也称为非虚拟接口习惯用法-为什么抽象方法是公共的?
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()
    { 

    }
}
 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");
    }
}