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

发布于 2024-09-03 06:55:37 字数 488 浏览 4 评论 0原文

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

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() 的建议。感觉不太好,有没有更好的办法?

我希望你能明白这个问题,对于我的英语不好,我深表歉意。

Can I somehow force a derived class to always call the overridden methods base?

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

And then in a derived class :

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

    // Do any work
}

I've searched and found a suggestion to use a non-virtual Update() but also a protected virtual UpdateEx(). It just doesn't feel very neat, isn't there any better way?

I hope you get the question and I am sorry for any bad English.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

缺⑴份安定 2024-09-10 06:55:37

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

听起来这基本上是您使用 UpdateEx - 尽管根据我的经验,它通常是 UpdateImpl 或类似的东西。在我看来,这种模式并没有什么问题——它避免了强制所有派生类编写相同代码来调用基方法的想法。

Use the template method pattern - don't override the base method which needs to do some work, override one specific bit, which can either be abstract or a no-op in the base class. (The decision about whether to make it a no-op or abstract is usually fairly obvious - does the base class make sense on its own, as a concrete class?)

It sounds like this is basically the pattern you've found with UpdateEx - although it's usually UpdateImpl or something similar in my experience. There's nothing wrong with this as a pattern, in my view - it avoids any idea of forcing all derived classes to write the same code to call the base method.

雅心素梦 2024-09-10 06:55:37

我花了一些时间才了解 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() 扩展它。

This took me a bit to get what Update and UpdateEx would look like. Here's a code example that might help others.

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

A subclass will never have any implementation for Update(). It'll uses UpdateEx() to add implementation to Update();

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

Any instance of ConcreteClass will use the BaseClass implementation of Update() along with however ConcreteClass extends it with UpdateEx().

若沐 2024-09-10 06:55:37

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

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

I think that the suggestion which you found is good.

The only base class method which you can't avoid calling from the subclass in base class constructor.

忆悲凉 2024-09-10 06:55:37

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

根据您的用例,您可能希望使用 event 来代替,但实现事件的通常模式是拥有一个子类可以重写的虚拟 OnEvent 方法,而不是添加事件处理程序,因此在您的示例中,它归结为同一件事。

I think having a non-virtual base member that calls a virtual "hook" that can be extended is the most common solution for this kind of problem.

Depending on your use case, you might want to use an event instead, but the usual pattern for implementing an event is to have a virtual OnEvent method that subclasses can override instead of adding an event handler, so in your example case it boils down to the same thing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文