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

Mat*_*röm 22 c# inheritance overriding base

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

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

然后在派生类中:

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

    // Do any work
}
Run Code Online (Sandbox Code Playgroud)

我搜索过并发现了一个使用非虚拟Update()的建议,还有一个受保护的虚拟UpdateEx().它只是感觉不是很整洁,有没有更好的方法?

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

Jon*_*eet 31

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

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

  • 虽然我同意模板方法模式通常更可取,但应该注意的是BCL大量使用"覆盖必须调用基类方法"(反?)模式.Windows Forms类尤其如此. (2认同)
  • 如果你有一个两层深的层次结构,你仍然想在所有层次上强制进行基本调用,这是否意味着你得到了一个“UpdateImpl2”? (2认同)

Sha*_*rly 7

我花了一些时间才了解 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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