Make sure base method gets called in C#

偶尔善良 提交于 2019-12-18 14:02:14

问题


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.


回答1:


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.




回答2:


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().




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/2945147/make-sure-base-method-gets-called-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!