确保在C#中调用基本方法

时间:2010-05-31 17:45:19

标签: c# inheritance override base

我可以以某种方式强制派生类始终调用重写的方法基础吗?

public class BaseClass
{
    public virtual void Update()
    {
        if(condition)
        {
            throw new Exception("..."); // Prevent derived method to be called
        }
    }
}

然后在派生类中:

public override void Update()
{
    base.Update(); // Forced call

    // Do any work
}

我搜索并发现了使用非虚拟Update()以及受保护的虚拟UpdateEx()的建议。它感觉不是很整洁,是不是有更好的方法?

我希望你能得到这个问题,我很抱歉任何不好的英语。

4 个答案:

答案 0 :(得分:29)

使用template method pattern - 不要覆盖需要做一些工作的基本方法,覆盖一个特定的位,它可以是抽象的,也可以是基类中的无操作。 (关于是否使其成为无操作或抽象的决定通常是相当明显的 - 基类本身是否有意义,作为具体类?)

听起来这基本上是你用UpdateEx找到的模式 - 虽然它通常是UpdateImpl或类似的经验。在我看来,作为一个模式,这没有任何问题 - 它避免强迫所有派生类编写相同的代码来调用基本方法。

答案 1 :(得分:2)

我认为您发现的建议很好。

唯一不能避免从基类构造函数中的子类调用的基类方法。

答案 2 :(得分:2)

我认为拥有一个非虚拟基础成员可以调用可以扩展的虚拟“钩子”,这是解决此类问题的最常见方法。

根据您的使用情况,您可能希望使用event,但实现事件的通常模式是使用虚拟OnEvent方法,子类可以覆盖而不是添加事件处理程序,所以在你的例子中它归结为同样的事情。

答案 3 :(得分:2)

这让我有点了解Update和UpdateEx的样子。这是一个可能对其他人有帮助的代码示例。

public class BaseClass
{
    // This is the Update that class instances will use, it's never overridden by a subclass
    public void Update()
    {
        if(condition);
        // etc... base class code that will always run

        UpdateEx(); // ensure subclass Update() functionality is run
    }

    protected virtual void UpdateEx()
    {
        // does nothing unless sub-class overrides
    }
}

子类永远不会有Update()的任何实现。它将使用UpdateEx()将实现添加到Update();

public class ConcreteClass : BaseClass
{
    protected override void UpdateEx()
    {
        // implementation to be added to the BaseClass Update();
    }
}

ConcreteClass的任何实例都将使用Update()的BaseClass实现,但ConcreteClass使用UpdateEx()扩展它。