11

I have an abstract class with constructor XYZ(string name).
Also I have a class that inherits from that abstract class.

How to force inherited class to call base(string name)?

Now I can use new Inherited() and it will not call base constructor. I want to force user to implement default constructor in inherited class.

apocalypse
  • 5,764
  • 9
  • 47
  • 95

4 Answers4

20

A class without an explicit constructor has a parameterless constructor. In the other hand, if you implement a constructor with parameters and no paramterless constructor, your class won't be instantiable without arguments.

In other words:

public abstract class A 
{
    public A(string x) 
    {
    }
}

public class B : A 
{
    // If you don't add ": base(x)" 
    // your code won't compile, because A has a 
    // constructor with parameters!
    public B(string x) : base(x)
    {
    }
}

That is, if A has a parameterless constructor (or no explicit constructor), B will automatically call the base constructor. You don't need to code any further stuff here.

Otherwise, if your base class has a parameterless constructor and a constructor with parameters, you can't force a derived class to automatically call a constructor excepting the default one (i.e. the so-called parameterless constructor).

Workaround

Well, there's no special workaround here, but be aware C# supports optional parameters in both constructors and methods.

If you want to be 100% sure derived classes will call a concrete base constructor, you can implement your base class using a single parameterless constructor with optional parameters and use this instead of constructor overloading:

public class A
{
    public A(string x = "hello world") // or just string x = null
    {

    }
}

Now if a B class derived A, B will always call A's base constructor, since x is optional and it has a default value.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
4

How to force inherited class to call base(string name)

Make parameterless constructor in your abstract class private, or not add it at all. That's will force all derived classes to call the constructor you specified or there will be a compile error.

public abstract class BaseClass
{
    protected BaseClass(string parameter)
    {
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass()
    {
    }
}

Will end up with

'`Project.BaseClass`' does not contain a constructor that takes 0 arguments
MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
1

You don't need to do anything. All derived class constructors must call a base class constructor (except for some particularly evil hacks, that you probably don't need to worry about). If none is explicitly specified in code, an implicit call to the base class's parameterless constructor is implied. If the base class has no parameterless constructor (as is the case if you add a constructor accepting a string and don't explicitly add a parameterless constructor), the class will not compile.

Servy
  • 202,030
  • 26
  • 332
  • 449
0

I have spent the last half hour or so experimenting once again with permutations of an abstract base class that has its default constructor marked as private and an overload that takes 4 parameters, and a derived class that has only the 4-parameter overload. Using the latest C# compiler (7.3), it is evident that in this situation:

  1. The derived class must explicitly define the 4-parameter overload.
  2. The overload in the derived class call to the 4-parameter overload must be explicit.

Base Class Constructor Signature

public OperatingParameterBase (
    string pstrInternalName ,
    string pstrDisplayName ,
    T penmParameterType ,
    U penmDefaultParameterSource )

Derived Class Constructor

internal OperatingParameter (
    string pstrInternalName ,
    string pstrDisplayName ,
    T penmParameterType ,
    U penmDefaultParameterSource )
    : base (
          pstrInternalName ,
          pstrDisplayName ,
          penmParameterType ,
          penmDefaultParameterSource )
{
}   // internal OperatingParameterExample constructor

I showed the whole constructor in the derived class to demonstrate that calling the base class constructor is its only absolute requirement. Since the work of the base constructor is irrelevant to this discussion, I left it out.

David A. Gray
  • 1,039
  • 12
  • 19