调用基函数然后继承函数

Dav*_*ave 49 c# inheritance

我有一个基类和一个继承基类.基类有几个虚函数,继承的类可以覆盖它们.但是,基类中的虚函数必须在调用继承的类重写之前运行.有没有什么方法可以先调用基类虚函数然后继承类重写.不调用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(); */ }
}
Run Code Online (Sandbox Code Playgroud)

类似的问题在这里.

Chr*_*ich 70

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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是任何继承的类都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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

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


dtb*_*dtb 54

可以在.NET框架中找到一个常见的解决方案是在一个公共方法拆分的方法XXX和被保护的,虚拟方法OnXXX由所述公共方法调用.对于您的示例,它看起来像这样:

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

    protected virtual void OnMyMethod()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

class MyInherited : MyBase
{
    protected override void OnMyMethod()
    {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Dave:不,在虚方法调用之前或之后,没有办法神奇地调用重写的基本方法.你必须以某种方式拆分它.(如果将其拆分,除了在受保护方法之前和之后执行某些操作外,还可以强制执行重写方法调用重写的基本方法.) (3认同)
  • 这也称为非虚拟接口习惯用法 - http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface (3认同)