c# - 如何调用base.base.method()?

标签 c# polymorphism

// Cannot change source code
class Base
{
    public virtual void Say()
    {
        Console.WriteLine("Called from Base.");
    }
}

// Cannot change source code
class Derived : Base
{
    public override void Say()
    {
        Console.WriteLine("Called from Derived.");
        base.Say();
    }
}

class SpecialDerived : Derived
{
    public override void Say()
    {
        Console.WriteLine("Called from Special Derived.");
        base.Say();
    }
}

class Program
{
    static void Main(string[] args)
    {
        SpecialDerived sd = new SpecialDerived();
        sd.Say();
    }
}

结果是:

Called from Special Derived.
Called from Derived. /* this is not expected */
Called from Base.

如何重写 SpecialDerived 类,以便不调用中间类“Derived”的方法?

更新: 我想从 Derived 而不是 Base 继承的原因是 Derived 类包含许多其他实现。由于我不能在这里执行 base.base.method(),我想最好的方法是执行以下操作?

//无法更改源代码

class Derived : Base
{
    public override void Say()
    {
        CustomSay();

        base.Say();
    }

    protected virtual void CustomSay()
    {
        Console.WriteLine("Called from Derived.");
    }
}

class SpecialDerived : Derived
{
    /*
    public override void Say()
    {
        Console.WriteLine("Called from Special Derived.");
        base.Say();
    }
    */

    protected override void CustomSay()
    {
        Console.WriteLine("Called from Special Derived.");
    }
}

最佳答案

只是想在这里添加这个,因为即使经过很多次人们仍然会回到这个问题。当然这是不好的做法,但仍然可以(原则上)做作者想做的事情:

class SpecialDerived : Derived
{
    public override void Say()
    {
        Console.WriteLine("Called from Special Derived.");
        var ptr = typeof(Base).GetMethod("Say").MethodHandle.GetFunctionPointer();            
        var baseSay = (Action)Activator.CreateInstance(typeof(Action), this, ptr);
        baseSay();            
    }
}

关于c# - 如何调用base.base.method()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2323401/

相关文章:

c# - 将字典序列化为json文件

java - Java中的多态与继承与抽象类的静态方法

c++ - 当基类指针指向在基类中声明的派生类虚函数时,为什么会出现编译时错误?

c++ - 我收到一条错误消息,指出只有虚拟函数可以标记为覆盖

c# - 电子商务网站的不同搜索结果

c# - 数据绑定(bind)后 telerik radgrid 的客户端绑定(bind)未更新

c# - 如何摆脱子项 ObjectListView 中的复选框文本

c# - 在异步方法上调用 .Wait() 和 Task.Run().Wait() 之间的区别

c++ - C++如何从父类继承方法

Java 1.6 -> 1.8,同样删除编译错误