6

I'm having a hard time coming up with a good naming convention for methods in derived classes that serve the same purpose as the methods in the base class. For example, if both the base class, and the derived class, need to initialize:

public class Foo()
{
    public void Initialize()
    {
        // base class initialization code here
        InitializeDerived();
    }

    // force derived classes to implement their own initialize method
    protected abstract void InitializeDerived();
}

public class Bar() : Foo
{
    protected override void InitializeDerived()
    {
        // initialization code here
    }
}

InitializeDerived() seems clunky. The only other option I can think of is to make the base class Initialize() method virtual. Then the derived class could override it, using the same name, and call the base class Initialize() method first.

Is there a better way? A better naming convention?


This may be a better example, because constructors won't solve the problem here. In this example, we have a rules engine where the client code polymorphically calls Process() on each rule:

public class RuleBase()
{
    public void Process()
    {
        // base class processing code here
        ProcessDerived();
    }

    // force derived classes to implement their own process method
    protected abstract void ProcessDerived();
}

public class RuleValidateHeight() : RuleBase
{
    protected override void ProcessDerived()
    {
        // derived class processing code here
    }
}

The consuming code:

foreach (Rule rule in rules)
{
    rule.Process()
}
  • This might sound terrible but you could use a number suffix like Initialize2. That way you also have the option of marking the Initialize2 sealed and then passing control down again to Initialize3 – Steve Vermeulen Dec 15 '17 at 7:32
11

In game programming I'm pretty used to the prefix 'On' so that you can think of the base class generating an 'event' when something is about to happen.

protected override void OnInitialize() { /*code here*/ }
protected override void OnProcess() { /*code here*/ }

This is called the Template Method Pattern, by the way.

As Martin comments below, other useful 'event' prefixes include Pre and Post. In a game context you'd typically have PreUpdate OnUpdate PostUpdate.

  • 3
    I like this. Also consider PreProcess() and PostProcess() to emphasis when the method will be called in case it's important to do the stuff after or before the parent Process(). – Martin Wickman Mar 20 '13 at 12:34
  • @MartinWickman Thank you for the pre- and post- tip. I like that. – Bob Horn Mar 20 '13 at 13:07
4

Use constructors for this instead.

public class Foo
{
    public Foo()
    {
        // initialization code here
    }
}

public class Bar : Foo
{
    public Bar()
        : base() // base (Foo) constructor gets called first.
    {
        // initialization code for Bar goes here
    }
}

There are many reasons why, but the most compelling one is that newing up an object this way guarantees that you get back an object that is fully initialized on construction.

  • +1 for the tip. I may even be able to use your suggestion. The problem is that I'm dealing with some convoluted legacy code, and I may not be able to simply do what you suggest. We'll see. Thanks. – Bob Horn Mar 19 '13 at 20:07
  • I just added a different scenario. Same problem, different slant. If you have any advice, it would be appreciated. – Bob Horn Mar 19 '13 at 21:58
  • See my new answer. – Robert Harvey Mar 19 '13 at 22:04
  • I don't like this kind of answers which dictate the question owner to use a different tool/approach instead of suggesting a possible solution to the problem described. Clearly he's looking for an advice for naming a tool which is already provided by the language itself. The tool he's using is completely different than the suggested tool in this answer. Therefore, this answer is very polluting in my opinion. – Xtro Nov 25 '17 at 22:31
  • @Xtro: Thanks for your opinion, but you might want to check the chronology of the posts here. The OP didn't make it clear that constructors wouldn't work until 2 hours after I posted my answer, and leaving my answer here helps people reading the post to figure out what happened. Also, note that the post you're commenting on is over four years old; it is, quite literally, ancient history. – Robert Harvey Nov 26 '17 at 1:05
3

Well, this is going to be easier if you can call Process from the derived class, and work your way up the inheritance tree instead of down:

public class Bar: Foo
{
    public override void Process()
    {
         base.Process();  // optional
         // Process Derived Rule here.
    }
}
  • +1 (again). I can't do this now, but I'll try this approach. I think this is exactly what I needed. Thanks! – Bob Horn Mar 19 '13 at 22:35
  • 4
    One thing I don't like about this approach is that if the call to base.Process() is not optional, developers must remember to add that line for each derived class. – congusbongus Mar 20 '13 at 2:59
  • 1
    @CongXu: It's not that hard to remember; you're deliberately overriding the base class's Process() method. – Robert Harvey Mar 20 '13 at 4:17
  • 2
    @RobertHarvey the difference between 'not that hard to remember' and 'impossible to forget' is a big one - IME code using this pattern in a team with many developers does result in the base not getting called where it should. – Pete Kirkham Mar 20 '13 at 10:51
  • 1
    @CongXu has a good point. If the shared code is in the base class, and really must be called for things to work correctly, being optional isn't good. I think the template method design pattern is the way to go here, but then I'm back to my naming problem. – Bob Horn Mar 20 '13 at 12:28
2

The name of the method should say what the method does, instead of just saying where the method appears. Possible names would be:

ProcessRuleSpecifics
ProcessAfterInitialization
ResumeProcess
TerminateProcess

and so on

  • Why is this better than ProcessDerived? – Robert Harvey Mar 19 '13 at 22:06
  • 2
    It says what it does instead of just saying where it is declared. – Olivier Jacot-Descombes Mar 19 '13 at 22:11

protected by gnat Sep 25 '16 at 13:17

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.