强制从基类调用基方法的方法

4

如果我使用"override"属性创建方法,派生方法不会自动调用基类方法的实现,我需要使用"base"关键字手动调用它,像这样:

public class A
{
    public virtual void Say()
    {
        Console.Write("A");
    }
}

public class B : A
{
    public override void Say()
    {
        base.Say();
        Console.Write("B");
    }
}

只有在这种情况下,字符串"A"和"B"才会被写入控制台。所以问题是我如何摆脱"base.Say();"行?所以我想强制每个派生方法“Say”调用基类中的基本方法。这可能吗?我正在寻找任何解决方案,即使我被迫使用其他关键字。

这听起来像是 X-Y 问题;针对未定义问题的提议解决方案的问题。是什么真正的业务需求促使您进行此次询问? - Pieter Geerkens
1
简短的回答是:不行。按照您所描述的方式是不可能的。 - sstan
我一般是在询问这个问题,因为有很多情况需要使用这个功能。 - Eugen1344
1个回答

11
虽然不能直接实现这一点,但您可以编写自己的方法,该方法不是虚拟的,并在执行某些固定操作后调用虚拟方法以获得相同的效果:
public class A
{
    public void Say()
    {
        Console.Write("A");
        SayImpl();
    }
    protected virtual void SayImpl()
    {
        // Do not write anything here:
        // for the base class the writing is done in Say()
    }
}

public class B : A
{
    protected override void SayImpl()
    {
        Console.Write("B");
    }
}

现在任何继承自A并实现 SayImpl() 的类都会在其打印输出之前加上A


1
谢谢!但我很好奇为什么C#开发人员没有添加覆盖方法实现的功能?那是非常好的功能,我经常需要它。 - Eugen1344
5
这正是C#已经支持的。现在,自动调用基类方法作为重写的一部分,那就是另外一回事了。而且,您必须考虑到并非所有开发人员都希望默认启用该行为。此外,如果您想要在覆盖方法之后而不是之前调用基础方法,或者想要在中间或基于条件的情况下调用该方法,该怎么办呢?保持显式是最好和最灵活的选择。 - sstan
2
如果您需要这么多次,那么您有一组有趣的要求。我很少需要指定调用者如何调用基本方法。此外,有一个如此简单的解决方法也是不创建特殊功能的一个很好的理由。功能需要花费金钱。 - John Saunders
@Eric 这取决于设计。我没有将其抽象化以模仿帖子中的层次结构,但通常情况下,我更喜欢将所有非叶类都设为abstract(并将所有叶类都设为sealed)。 - Sergey Kalinichenko
@sstan 我认为可以创建新的关键字。例如 "extended"。这样,您就可以编写 "public extended void Say()" 来使此方法成为基类的扩展方法。 - Eugen1344

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接