tags:

views:

114

answers:

5

I know it's not possible to inherit constructors in C#, but there's probably a way to do what I want to do.

I have a base class that is inherited by many other classes, and it has an Init method that does some initializing taking 1 parameter. All other inheriting classes also need this initializing, but I'd need to create separate constructors for all of them that would like like this:

public Constructor(Parameter p) {
    base.Init(p);
}

That totally violates the DRY principles! How can I have all necessary stuff initialized without creating dozens of constructors?

+3  A: 

Change the init function to it is the constructor for the base class, and then call it from the inherited objects like this:

public InheritedObject(Parameter p) : base(p)
{
}

The base constructor will be invoked before any code in the constructor itself runs.

AHM
+6  A: 

You don't create loads of constructors, all with the same code in; you create only one, but have derived classes call the base constructor:

public class Base
{
   public Base(Parameter p)
   {
     Init(p)
   }
}

public class Derived : Base
{
   public Derived(Parameter p) : base(p)
   {

   }
}
Rob Levine
That's what I need. Although I will have to create constructors for classes that don't have them, I won't have to repeat the code.
Alex
+2  A: 

Something like this?

public Constructor(Parameter p) : base(p) {

}

And the base class:

public Base(Parameter p)
{
    Init(p);
}

You can even mark your Init method as virtual, so you can do some sweet override in your other classes, if need be! ;)

public virtual void Init() { }

and in your other classes:

public override void Init() { base.Init(); //Do other stuff }
Arcturus
Although you have to be very careful calling a virtual method from a constructor - the subclass' constructor will not have run when the overridden method gets called by the superclass, so member variables etc would not have been initialized.
thecoop
true :) but you will find that issue really quick..
Arcturus
The virtual init method seems pointless, though. Normaly you should avoid doing work in constructors, and only use them for initialization, and if it is only initializing, then why not just use the constructor?
AHM
+2  A: 

The only way to not repeat the base.Init call is to instead call the base constructor

class Base
{
  public Base(Parameter p)
  {
    this.Init(p)
  }

  private void Init(Parameter p)
  {
      ...
  }
}

class Inherited : Base
{
   public Inherited(Parameter p)
     : base(p)
   {
      // other constructor logic, but Init is already called.
   }
}
Jamiec
+1  A: 

You can't inherit constructors but you can call them from your derived children's constructors. If you make the base classes default constructor private it will force you to select a base constructor every time you create a derived class.

class A
{
    protected A(int x)
    {

    }
}
class B : A
{
    B(int x)
        : base(x)
    {

    }
}
rerun