Common Type System—Constructor Chaining
Constructor Chaining (Language Feature)
When deriving from existing types, the base type’s constructor may be called. In fact, it is required in C# to ensure that base classes are able to construct state correctly. Without doing so, executing any code on the derived type could result in unpredictable behavior. This chaining happens by convention in C# before the body of a derived type’s constructor executes.
If you don’t explicitly state the base type constructor overload to call, the C# compiler will automatically
utilize the base type’s default constructor. If one does not exist, C# will give you a compilation error. For
example, consider CtorExampleDerived, which uses the above-defined class CtorExample as its base
type:
class CtorExampleDerived : CtorExample { private DateTime initializedDate; public CtorExampleDerived(int value) : base(value * 2) { initializedDate = DateTime.Now; } }
Notice that this constructor makes a call to the base constructor, using C#’s special syntax. It looks much
like a function call—where base is the constructor function—and indeed the constructor matching
happens depending on how many parameters are passed to base, precisely as method overload resolution
happens. The call to the base constructor executes to completion before initializedDate is set by
CtorExampleDerived’s constructor. If we hadn’t specified the target constructor, the C# compiler
would fail because CtorExample (the version above that takes an integer) doesn’t have a parameterless
constructor.
You can also chain constructors across overloads on a single type. This can be used in a fashion similar to
method overloading, for example to define default values and avoid redundant code. The syntax is very
similar to base above, except that you use this instead:
class CtorExampleDerived : CtorExample { private bool wasDefaultCalled; private DateTime initializedDate; public CtorExampleDerived() : this(0) { wasDefaultCalled = true; } public CtorExampleDerived2(int value) : base(value * 2) { initializedDate = DateTime.Now; } }
This code uses the default constructor to supply a default value. Of course, both constructors can do
more than just forwarding. The default constructor might perform additional operations, for example
setting wasDefaultCalled to true in the above example.
|

