Constructors and Destructors

Constructors and destructors in a base class are not inherited in the derived class. A derived class has a base portion and a derived portion. The base constructor initializes the base portion, and the constructor of the derived class initializes the derived portion. For the derived object, the default constructor of the base class is called by default to initialize the state of the base class. If the base class does not have a default constructor, a compiler error occurs unless the derived class calls a constructor in the base class that has parameters. In the following code, ZClass does not have a default constructor. A compiler error will occur:

public class ZClass {
    public ZClass(int param) {
    }
}

public class YClass : ZClass {
}

You might want to use something other then the default constructor for the base portion of a derived class. In the derived class, you can call a constructor other than the default constructor in the base class. These constructors can be called from the derived class using a constructor initializer list. The initializer list applies only to instance constructors of a derived type.

Here is the constructor initializer syntax:

accessibility modifier typename(parameterlist1) : base(parameterlist2){body}

The constructor initializer list follows the constructor name and colon operator. The base keyword refers to the base class constructor, while parameterlist2 determines which overloaded base class constructor is called. Parameters of the derived constructor can be used in the parameter list of the base class constructor to pass parameters up the hierarchy to the base class constructor.

In the following example, the YClass constructor explicitly calls the one-argument constructor of the base class:

public class ZClass {
    public ZClass(int param) {
    }
}

public class YClass : ZClass {
    public YClass(int param) : base(param) {
    }
}

Instances of a derived type are created inside-out. The base element is created and initialized first, and then the derived elements. In support of this model, the constructors are walked bottom-up. This facilitates passing parameters from derived constructors to base constructors. After the parameters are passed up the class hierarchy, the constructors are executed top-down, beginning with the constructor in the root class.

The following code confirms that constructor initializers are called bottom-up, but the constructors are invoked top-down, starting with the constructor in the base class:

using System;

namespace Donis.CSharpBook {

    public class Starter {
        public static void Main() {
            XClass obj = new XClass();
        }
    }


    public class ZClass {
        public ZClass(int param) {
            Console.WriteLine("ZClass constructor");
        }
    }

    public class YClass : ZClass {
        public YClass(int param) : base(YClass.MethodA()) {
            Console.WriteLine("YClass constructor");
        }

        public static int MethodA() {
            Console.WriteLine("YClass constructor initializer");
            return 0;
        }
    }

    public class XClass : YClass {
        public XClass() : base(XClass.MethodA()) {
            Console.WriteLine("XClass constructor");
        }

        public static new int MethodA() {
            Console.WriteLine("XClass constructor initializer");
            return 0;
        }
    }
}

The following is the output from the preceding code, which confirms the order of constructor initializer lists and the actual invocation of constructors:

XClass constructor initializer
YClass constructor initializer
ZClass constructor
YClass constructor
XClass constructor

Objects are not fully created until the constructor has finished completely. Therefore, the this reference of the derived type cannot be used as a parameter in the base class constructor initializer list:

public class ZClass {
    public ZClass(YClass obj) {
    }
}

public class YClass : ZClass {
    public YClass() : base(this) {  // Illegal
    }
}

Destructors are called in reverse order of constructors. Derived objects are destroyed outside-in, where the most-derived component is destroyed first. Correspondingly, destructors are called bottom-up. Because destructors are parameterless, there is no information to pass from derived to base class destructors. The derived class destructor automatically calls the base class destructor.

The following code has three classes—each with a destructor—that form a class hierarchy. At the end of the program, the destructors are invoked bottom-up, which confirms the sequencing of destructors:

using System;

namespace Donis.CSharpBook {

    public class Starter {
        public static void Main() {
            XClass obj = new XClass();
        }
    }

    public class ZClass {
        ~ZClass() {
            Console.WriteLine("ZClass destructor");
        }
    }

    public class YClass : ZClass {
        ~YClass() {
            Console.WriteLine("YClass destructor");
        }
    }

    public class XClass : YClass {
        ~XClass() {
            Console.WriteLine("XClass destructor");
        }
    }
}

This is the output from the program:

XClass destructor
YClass destructor
ZClass destructor
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.28.107