#694 – Sequence of Events for Chained Constructors

When you chain constructors together using the this keyword, one constructor calls another while an object is being created.

When one constructor chains to another, the constructor being chained to is executed first, followed by the body of the original constructor.

For example, assume that we have three Dog constructors, as shown below.

        public Dog(string name, int age, string favToy)
        {
            Console.WriteLine("name/age/favToy constructor executing");
        }

        public Dog(string name, int age)
            : this(name, age, "ball")
        {
            Console.WriteLine("name/age constructor executing");
        }

        public Dog(string name)
            : this(name, 1)
        {
            Console.WriteLine("name constructor executing");
        }

If we create a Dog object and pass it only a single argument, of type string, the code in the body of each constructor will be executed in the following order:

  • name/age/favToy constructor
  • name/age constructor
  • name constructor

 

#692 – Two Approaches for Optional Parameters in Constructors

When you create an instance of an object, you may want to pass different combinations of parameters for purposes of initializing the object.  In authoring a class, there are a couple different ways to support this.

You can declare multiple constructors, each supporting a different set of parameters.  You can use constructor chaining to invoke the main constructor, to centralize object initialization.

        public Dog(string name, int age, string favToy )
        {
            // Do all parameter validation here
            Name = name;
            Age = age;
            FavoriteToy = favToy;
        }

        public Dog(string name) : this(name, 1, null)
        {
        }

        public Dog(string name, int age) : this(name, age, null)
        {
        }

        public Dog(string name, string favToy) : this(name, 1, favToy)
        {
        }

You can also use optional parameters in a single constructor, to do the same thing.

        public Dog(string name, int age = 1, string favToy = null)
        {
            // Do all parameter validation here
            Name = name;
            Age = age;
            FavoriteToy = favToy;
        }

#645 – You Can Chain to the Default Constructor for a struct

You can use the this keyword in a constructor within a struct to invoke other constructors (constructor chaining).

public BoxSize(double x, double y)
    : this(x, y, 1.0)
    {
    }

Every struct also has a default parameterless constructor that you can explicitly invoke when creating an object of the struct’s type.

            BoxSize bs = new BoxSize();

Additionally, you can use the this keyword to chain to this default constructor from another constructor.  Doing so results in all fields being assigned to default values.

        // Initialize x and y to specified values,
        //   initialize z to default value.
        public BoxSize(double x, double y)
            : this()
        {
            this.x = x;
            this.y = y;
        }

#290 – Chaining Constructors

You can have one constructor in a class call another.  This is known as constructor chaining.

With constructor chaining, one constructor calls another to help it initialize the data in the class.

As an example, assume that we have a Dog class with two constructors, one which accepts name and age parameters, and one which accepts only a name parameter.

In the example below, the constructor that takes two arguments initializes both name and age properties.  The constructor that takes only a name parameter chains to the first constructor, passing it the name parameter and a default value for age.  This first constructor is called using the this keyword.

    public class Dog
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public Dog(string name)
            : this(name, 1)
        {
        }
    }