Make sure base method gets called in C#

10,900

Solution 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.

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

Solution 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.

Solution 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.

Share:
10,900

Related videos on Youtube

Matteus Hemström
Author by

Matteus Hemström

Currently working for Nuway AB in Sweden. Interested in software development in general. Sometimes I write stuff at matteus.ninja. Keeping myself busy with my own little company Teuz.

Updated on April 23, 2022

Comments

  • Matteus Hemström
    Matteus Hemström about 2 years

    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.

  • hemp
    hemp almost 14 years
    While I agree that the template method pattern is often preferable, it should be noted that the BCL makes heavy use of the "overrides must call the base class method" (anti?)pattern. This is particularly true of Windows Forms classes.
  • Dirk Boer
    Dirk Boer almost 9 years
    If you have a hierarchy of two levels deep where you still want to force the base call on all levels, does that mean you get an UpdateImpl2?
  • Jon Skeet
    Jon Skeet almost 9 years
    @DirkBoer: You mean if all "grandchild" classes should end up with three methods being called? If so, then yes, something like that - but I'd try to simplify the design at that point.
  • Dirk Boer
    Dirk Boer almost 9 years
    You're probably right. Maybe an OnCreate event or something like that makes more sense. Thanks for your quick answer!
  • James Hurley
    James Hurley over 7 years
    With this, the order in which the base method and children methods get called is easily controlled, which is another plus IMO.