27

I have the following hierarchy:

class Base
{
  public Base(string sMessage)
  {
     //Do stuff
  }
}

class Derived : Base
{
  public Derived(string someParams)
  {

   string sMessage = "Blah " + someParams;

   //Here I want to call the base constructor
   //base(sMessage);

  }

}
DotnetDude
  • 11,617
  • 35
  • 100
  • 158

7 Answers7

21

You have to call the base class constructor prior to the derived class constructor's body.

class Derived : Base
{
  public Derived(string someParams)
    : base("Blah " + someParams)
  {

  }

}
OregonGhost
  • 23,359
  • 7
  • 71
  • 108
  • This is probably the best solution for this simple case, but would get ugly pretty quickly if constructing the parameter was much more complex. – tvanfosson Mar 09 '09 at 16:29
  • That's true, though you could also construct the parameter in a static method and pass the result to the base class constructor. I prefer that over the hook approach. Or, since this is .NET, you could remove the things from the constructor and do it in the setters, which is serialization-friendly. – OregonGhost Mar 09 '09 at 17:09
12

I originally missed OregonGhost's comment about using a static method to modify the parameter, which turned out to be the most useful for me, so I thought I'd add a code sample for others who read this thread:

class Base
{
    public Base( string sMessage )
    {
        // Do stuff
    }
}

class Derived : Base
{
    public Derived( string sMessage ) : base( AdjustParams( sMessage ) )
    {
    }

    static string AdjustParams( string sMessage )
    {
        return "Blah " + sMessage;
    }
}
9

You can't. You can call it before:

public Derived() : base()

or you have to use a hook

class Base
{
  protected void init() { }
  public Base(string sMessage)
  {
     init();
  }
}

class Derived : Base
{
  public Derived(string someParams)
  {
   string sMessage = "Blah " + someParams;
   init();
  }
}
Dinah
  • 52,922
  • 30
  • 133
  • 149
  • Since the Base constructor is supposed to do stuff (presumable some stuff with sMessage), how does this code solve his problem? – wcm Mar 09 '09 at 15:57
  • If you use the hook, you need to have a way to avoid calling the default base constructor. See my answer for a way to avoid this by providing a constructor that doesn't run the initializer. – tvanfosson Mar 09 '09 at 15:58
  • @wcm: I'm just showing the steps to achieve the order of operations that DotnetDude needs. It looks like he understands C# well enough to alter the params and return object to fit his actual needs from here. – Dinah Mar 09 '09 at 16:10
  • @Dinah -- without a default constructor, this won't even compile. If you add a default constructor that calls init() then init() gets invoked twice: once in the base constructor and once in the derived constructor. If you implement with a hook you need to have a constructor that doesn't run it. – tvanfosson Mar 09 '09 at 16:20
4

If you really need to have your constructor run first, then I suggest using a protected Initialize method that is invoked by your constructors and does the actual work of initializing the class. You need to provide an alternate constructor that will allow the initialization to be skipped.

public class Base
{

    public Base() : this(true) { }

    protected Base(bool runInitializer)
    {
        if (runInitializer)
        {
            this.Initialize();
        }
    }

    protected void Initialize()
    {
        ...initialize...
    }
}

public class Derived : Base
{
    // explicitly referencing the base constructor keeps
    // the default one from being invoked.
    public Derived() : base(false)
    {
       ...derived code
       this.Initialize();
    }
}
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
1

Points to be noted on constructors:

· Constructors cannot be "virtual".

· They cannot be inherited.

· Constructors are called in the order of inheritance.

public Child(string a):base(a){}
Oscar Cabrero
  • 4,168
  • 8
  • 29
  • 49
0
public Derived(string someParams) : base(someParams)
{
    string sMessage = "Blah " + someParams;
}

This is the way you have to do it. You could perhaps put the code you want to call afterwards in a protected method in the base class and then you could call it afterwards like this:

class Base
{
  public Base(string sMessage)
  {
     ConstructorStuff();
  }

  protected Base()
  {
  }

  protected void ConstructorStuff()
  {
  }
}

class Derived : Base
{
  public Derived(string someParams)
  {    
   string sMessage = "Blah " + someParams;

   ConstructorStuff();       
  }    
}
Garry Shutler
  • 32,260
  • 12
  • 84
  • 119
  • 1
    This will run ConstructorStuff twice -- once when the default base constructor is invoked before the derived constructor and once during the execution of the derived constructor. – tvanfosson Mar 09 '09 at 16:03
  • Erm? Base doesn't have a default constructor that calls ConstructorStuff? – Garry Shutler Mar 09 '09 at 16:07
  • 1
    Ah. Then you need to provide a default constructor or the code won't compile since your derived class will need it. The problem still remains that the default constructor will need to use ConstructorStuff as well and you need an alternate that doesn't invoke the initializer. – tvanfosson Mar 09 '09 at 16:11
  • That'll learn me for missing out the "too obvious to bother" code from a basic C# question. The altered code will do what he wants now won't it? – Garry Shutler Mar 09 '09 at 16:14
  • The problem now is that every derived class is required to call the initializer. What I think you want is to have the initialize run by default but have a way to prevent it if necessary. This will do the job, but isn't IMO the best solution. – tvanfosson Mar 09 '09 at 16:26
0

Actually, the simplest solution is:

class Base
{
  public Base(string sMessage)
  {
     //Do stuff
  }
}

class Derived : Base
{
  public Derived(string someParams)
    : base("Blah " + someParams)
  {
  }

}

Why make it more complicated?

Tor Haugen
  • 19,509
  • 9
  • 45
  • 63