- An initializer of the form base(.) enables the current class's base class constructor-that is, the specific constructor implied by the form of the constructor called-to be called.
- An initializer taking the form this(.) enables the current class to call another constructor defined within itself. This is useful when you have overloaded multiple constructors and want to make sure that a default constructor is always called. Overloaded methods are covered in Chapter 6, but here's a quick and dirty definition: overloaded methods are two or more methods with the same name but different argument lists.
To see the order of events in action, note that the following code will execute the constructor for class A first and then the constructor for class B: -
using System; class A { public A() { Console.WriteLine("A"); } } class B : A { public B() { Console.WriteLine("B"); } } class DefaultInitializerApp { public static void Main() { B b = new B(); } }
This code is the functional equivalent to the following code in which the base class's constructor is called explicitly: -
using System; class A { public A() { Console.WriteLine("A"); } } class B : A { public B() : base() { Console.WriteLine("B"); } } class BaseDefaultInitializerApp { public static void Main() { B b = new B(); } }
Let's look at a better example of when constructor initalizers are useful. Once again, I have two classes: A and B. This time, class A has two constructors, one that takes no arguments and one that takes an int. Class B has one constructor that takes an int. The problem arises in the construction of class B. If I run the following code, the class A constructor that takes no arguments will be called: -
using System; class A { public A() { Console.WriteLine("A"); } public A(int foo) { Console.WriteLine("A = {0}", foo); } } class B : A { public B(int foo) { Console.WriteLine("B = {0}", foo); } } class DerivedInitializer1App { public static void Main() { B b = new B(42); } }
So, how do I ensure that the desired class A constructor will be called? By explicitly telling the compiler which constructor I want called in the initalizer list, like so: -
using System; class A { public A() { Console.WriteLine("A"); } public A(int foo) { Console.WriteLine("A = {0}", foo); } } class B : A { public B(int foo) : base(foo) { Console.WriteLine("B = {0}", foo); } } class DerivedInitializer2App { public static void Main() { B b = new B(42); } }
Unlike in Visual C++, you cannot use constructor initializers to access instance members, aside from constructors, of the current class.