views:

114

answers:

1

I have a class that first needs to call the derived class constructor before it calls the base constructor. I know that by the following code the base constructor will be called first

public class A {

    protected A () {
        //do something
    }

}

public class B : A {

    public B () : base() {
        //do something else
    }

}

Is their a way to reverse that order, or a work around for it. The solution with creating an additional protected method in the base-class like doConstructor() and call it in the derived constructor after the first task isn't possible with readonly fields because the compiler will not accept it.

+2  A: 

There's no direct way to accomplish this. In the past, I've encountered this situation too and used an Initialize method to work around it.

public class A
{
    protected A()
    {
        // Do pre-initialization here still.

        Initialize();
    }

    protected virtual Initialize()
    {
        // Do all post-derived-class initialization here.
    }
}

public class B : A
{
    public B()
        : base()
    {
    }

    protected override Initialize()
    {
        // Do initialization between pre- and post- initialization here.

        base.Initialize();
    }
}

As long as you follow the guidelines of pre-, post-, and normal initialization here, it could be reasonably safe and within good practice.

Noldorin
Template Method pattern
AB Kolan
It looks like you are reading the code off my screen ;o) We should be aware though that calling virtual members from constructors are usually advised against.
Fredrik Mörk
Calling virtual methods in the base-constructor (`A`) is a bit dangerous; `B`'s override is now running **before** `B`'s constructor, which could lead to problems with uninitialized fields. I would generally advise caution here, or better: a **post**-ctor `Initialize` step.
Marc Gravell
@Fredrik: Hehe, yeah. I'm not surprised this is the method other people use too. I wasn't aware that calling virtual members from constructors is advised against - any reason in particular? Anyway, I think it's quite safe in this case.
Noldorin
@Marc: Good point. I shall clarify the code a bit to show how this issue can be (at least partially removed).
Noldorin
@Fredrik... It's generally considered a bad idea because it will always call the derived method... In other words, deriving from a base class changes the execution of the base class itself... In this case that's okay, but in general changing the behaviour of a separate class like that is likely to break any dependent code that was relying on the old behaviour.
Andrew Rollings