C# – Force derived class to implement base class constructor with parameter(s)

cnet

Is it possible to enforce a compile-time contract on derived classes requiring implementation of a constructor (with parameter)?

I have a base class with a constructor requiring a parameter:

public class FooBase
{
  protected int value;
  public FooBase(int value) { this.value = value; }
  public virtual void DoSomething() { throw new NotImplementedException(); }
}

I'd like to force derivations of my base class to implement the same constructor:

public class Foo : FooBase
{
  public Foo(int value) : base(value) { }
  public override void DoSomething() { Console.WriteLine("Foo: {0}", value); }
}

If no constructor is implemented, derived classes causes a compiler error because there is no default constructor in the base class:

// ERROR: 'Does not contain a constructor that takes 0 arguments'
// Adding default constructor in FooBase eliminates this compiler error, but
// provides a means to instantiate the class without initializing the int value.
public class FooBar : FooBase
{
  public override void DoSomething() { Console.WriteLine("FooBar: {0}", value); }
}

Adding a default constructor, FooBar(), in the derived class silences the compiler error, but provides a dangerous means of instantiating FooBar without the required base class int value being initialized. Because I'm using a factory (see below), silencing the compiler error only results in a run-time error later. I'd like to force FooBar to implement FooBar(int)

INTERESTING OBSERVATION:

If a default constructor, FooBase(), is added to FooBase, then it is 'inherited' by derived classes that do not provide a constructor:

  1. Foo does not inherit the default constructor because it supplies an explicit constructor.
  2. FooBar DOES inherit FooBase().

HOWEVER, the same is not true with the non-default constructor FooBase(int)!

  1. Foo MUST explicitly implement FooBase(int) and call base(int).
  2. FooBar FAILS to 'inherit' the non-default constructor the same way that a default constructor is inherited!

I do not want a default constructor in the base class because instances are created using a factory method that supplies a needed "settings" parameter. That factory method is not illustrated here (which uses the Activator.CreateInstance() method).

Here is the way derived classes should be instantiated:

  static void Main(string[] args)
  {
    FooBase myFoo = new Foo(4);     // Works, since Foo(int) is implemented.

    // ERROR: 'Does not contain a constructor that takes 1 arguments'
    FooBase myFooBar = new FooBar(9);  // Fails to compile.
  }

Because I am using a factory–not direct instantiation as shown–there is no compiler error. Instead, I get a runtime exception: 'Constructor on type not found.'

Unworkable solutions:

  • Interfaces do not support constructors.
  • Constructors cannot be virtual or abstract.

It appears that supplying a base class cannot enforce a contract on constructors.

Work-around:

  • Provide a default constructor in base class along with property to pass settings parameter.

Best Answer

If a default constructor, FooBase(), is added to FooBase, then it is 'inherited' by derived classes that do not provide a constructor:

This is incorrect - constructors in general are never inherited. A default constructor is automatically provided for a class that does not provide any other constructor implementation.

You could put in a constraint on an interface that provides an Init() method for you:

public interface IInit
{
   void Init(int someValue);
}

public class FooBase : IInit
{
   ..
}