C# - Making all derived classes call the base class constructor

80,291

Solution 1

You do have to redeclare constructors, because they're effectively not inherited. It makes sense if you think of constructors as being a bit like static methods in some respects.

In particular, you wouldn't want all constructors to be automatically inherited - after all, that would mean that every class would have a parameterless constructor, as object itself does.

If you just want to call the base class constructor though, you don't need to write any code in the body of the constructor - just pass the arguments up to the base class as per Waleed's post.

If your base class starts requiring more information, it's natural that you should have to change all derived classes - and indeed anything calling the constructors of those classes - because they have to provide the information. I know it can seem like a pain, but it's just a natural consequence of what constructors do.

Solution 2

You can use the following syntax to call the base class constructor from the classes that derive from it:

public DerivedClass() : base() {
    // Do additional work here otherwise you can leave it empty
}

This will call the base constructor first, then it will perform any additional statements, if any, in this derived constructor.

Note that if the base constructor takes arguments you can do this:

public DerivedClass(int parameter1, string parameter2) 
    : base(parameter1, parameter2) {
    // DerivedClass parameter types have to match base class types
    // Do additional work here otherwise you can leave it empty
}

You can find more information about constructors in the following page:

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-constructors

In a derived class, if a base-class constructor is not called explicitly by using the base keyword, the default constructor, if there is one, is called implicitly.

Solution 3

I had the same problem, and I solved it by replacing my constructor with a factory method like this:

A is the parent class.

public static T getChild<T>(int number) where T:A, new()
{
    T child = new T();
    T._number = number;
    return child;

}

You can create a Child class with

Child b = A.getChild<Child>(2);

Solution 4

A kind of alternative could be to rely on a Dependency Injection container to initialize your objects, that way the that reference to the base class (could be the call to the base constructor or another initializer method) would "externalized" to the DI container.

I don't know if it makes sense to your case or not

Share:
80,291
Tom
Author by

Tom

Programming enthusiast and student, interested in C++ and various aspects of Web Development.

Updated on September 12, 2020

Comments

  • Tom
    Tom over 3 years

    I have a base class Character which has several classes deriving from it. The base class has various fields and methods.

    All of my derived classes use the same base class constructor, but if I don't redefine the constructor in my derived classes I get the error:

    Error: Class "child class" doesn't contain a constructor which takes this number of arguments

    I don't want to redefine the constructor in every derived class because if the constructor changes, I have to change it in every single class which, forgive any misunderstanding, goes against the idea of only writing code once?

  • Waleed Al-Balooshi
    Waleed Al-Balooshi over 13 years
    @user491704 glad to be of service
  • jasdefer
    jasdefer over 9 years
    Why is this not an answer to this question? It replaces an empty constructor public Child(int number) : base(number){} in every child class.
  • Hashem Qolami
    Hashem Qolami over 9 years
    Before @Ben edited the answer, it was like a "I'm having the same issue" post. I withdraw my first comment respectfully.
  • jasdefer
    jasdefer over 9 years
    Ah okay, you are right. It really sounded that way. Thanks for your remark.
  • Ben Voigt
    Ben Voigt over 9 years
    @HashemQolami: You do have to thoroughly read "I have the same issue" answers to see if they also offer a solution.
  • macio.Jun
    macio.Jun over 9 years
    public DerivedClass() : base() {}, redundant base constructor call
  • Jeppe Stig Nielsen
    Jeppe Stig Nielsen almost 9 years
    To make @macio.Jun's comment more explicit: If a non-static constructor overload (in a class) contains neither : base(...) nor :this (...), then a call to the zero-parameter base class constructor is implied. So if no chaining is mentioned explicitly, that is the same as writing : base(). Also, if no non-static constructors are written for a non-static class, the compiler will generate an empty zero-parameter constructor which chains : base().