调用基函数然后继承函数

时间:2010-09-19 22:19:24

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

类似问题here

6 个答案:

答案 0 :(得分:67)

C#不支持自动执行此操作,但是 您可以使用template method pattern强制执行此操作。例如,假设你有这个代码:

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能够执行。

答案 1 :(得分:49)

可以在.NET Framework中找到的常见解决方案是将方法拆分为公共方法XXX和受公共方法调用的受保护虚拟方法OnXXX。对于您的示例,它看起来像这样:

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

    protected virtual void OnMyMethod()
    {
    }
}

class MyInherited : MyBase
{
    protected override void OnMyMethod()
    {
        // do something
    }
}

答案 2 :(得分:2)

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

答案 3 :(得分:0)

除了你已经命名的两种方式之外,没有办法做你正在寻找的东西。

您可以在基类中创建2个函数,一个被调用,另一个虚拟。

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

答案 4 :(得分:0)

不完全是。但我使用抽象方法做了类似的事情。

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

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

答案 5 :(得分:0)

你怎么看待这个?

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

    }
}