#619 – Calling the Constructor in a Base Class

Because a derived class does not inherit any of the constructors of the base class, it must do all of the initialization that the base class normally does.  It normally does this by using the base keyword to call the constructor of the base class.

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

        public Dog(string name)
        {
            Console.WriteLine("In Dog constructor");
            Name = name;
        }
    }

    public class Terrier : Dog
    {
        public string Temperament { get; set; }

        public Terrier(string name, string temperament) : base(name)
        {
            Console.WriteLine("In Terrier constructor");
            Temperament = temperament;
        }
    }

In the example above, the sequence when creating a Terrier object is:

  • Client code passes in name and temperament
  • Terrier constructor invokes the Dog constructor using the base keyword and passing the name parameter
  • Dog constructor does its initialization
  • Terrier constructor does its initialization

 

#331 – Calling a Base Class Constructor Implicitly vs. Explicitly

In a derived class, you can call a constructor in the base class explicitly using the base keyword.

    public class Terrier : Dog
    {
        public string Attitude { get; set; }

        public Terrier(string name, int age, string attitude)
            : base(name, age)
        {
            Attitude = attitude;
        }

If you don’t explicitly call a base class constructor, the default (parameterless) constructor is called implicitly.

        public Terrier(string name, int age, string attitude)
        {
            // Default Dog constructor has already been called
            //   at this point.
            Name = name;
            Age = age;
            Attitude = attitude;
        }

If you do omit the base keyword, the base class must define a default (parameterless) constructor.  If it doesn’t, the compiler will complain that the base class doesn’t have a constructor that takes 0 arguments.

#330 – Derived Classes Do Not Inherit Constructors

A derived class inherits all of the members of a base class except for its constructors.

You must define a constructor in a derived class unless the base class has defined a default (parameterless) constructor.  If you don’t define a constructor in the derived class, the default constructor in the base class is called implicitly.

When you define a constructor in a derived class, you can call a constructor in the base class by using the base keyword.

Here’s an example:

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

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

    public class Terrier : Dog
    {
        public string Attitude { get; set; }

        // Call the Name/Age constructor in the base class
        public Terrier(string name, int age, string attitude)
            : base(name, age)
        {
            Attitude = attitude;
        }
    }

#314 – Access Modifiers Are Not Allowed on Static Constructors

Because you can’t call a static constructor directly, you can’t include an access modifier (e.g. public, private) when defining a static constructor.  Static constructors are defined without access modifiers.

        static Dog()
        {
            Motto = "We serve humans.  And lick ourselves.";
        }

The compiler will generate an error if you try to include an access modifier.

#313 – Accessibility of Constructors in a Class

You can apply access modifiers to instance constructors, dictating what code is allowed to create an instance of the class using a signature that matches the constructor.

  • public – All code has access
  • private – Only code in defining class has access
  • protected – Code in defining class or derived classes has access
  • internal – All code in defining assembly has access
  • protected internal – Code in defining assembly or in derived classes has access
        // All code
        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        // Only code in this class has access
        private Dog()
        {
            Name = "UNKNOWN";
            Age = 0;
        }

        // Code in this class or subclass has access
        protected Dog(string name)
        {
            Name = name;
            Age = 1;
        }

        // Code in same assembly has access
        internal Dog(int age)
        {
            Name = "INTERNAL";
            Age = age;
        }

        // Code in same assembly or derived classes has access
        protected internal Dog(double age)
        {
            Age = (int)age;
        }

#299 – Intellisense Shows You Available Constructors

If you have several different constructors define for a class or a struct, Intellisense in Visual Studio will show you the different constructors that you can use.

Assume that you have a Dog class, with two different constructors, as follows:

    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)
        {
        }
    }

Because we have these two constructors, we can pass in either one or two parameters when using the new operator to construct a new instance of a Dog.

            Dog d1 = new Dog("Lassie");
            Dog d2 = new Dog("Django", 6);

Visual Studio will tell us, through Intellisense, that there are two constructors available.  Once the constructor signature pops up, you can use the arrow keys to cycle through the two options.

#295 – When Is a Static Constructor Called?

You cannot dictate when a static constructor will be called and you can’t call it directly.

More specifically, a static constructor will be called just before you do one of the following:

  • Create an instance of the type
  • Access any static data in the type
  • Start executing Main method (in the same class as the static constructor)

If we have the following implementation in the Dog class:

        public Dog(string name)
        {
            Console.WriteLine("Dog constructor");
            Name = name;
        }

        public static string Motto = "Wag all the time";

        static Dog()
        {
            Console.WriteLine("Static Dog constructor");
        }

And we create a Dog instance:

 Console.WriteLine("Here 1");
 Dog d1 = new Dog("Kirby");
 Console.WriteLine("Here 2");

We get this output (static constructor called before object instantiation):

Or if we access static data:

            Console.WriteLine("Here 1");
            string s = Dog.Motto;
            Console.WriteLine("Here 2");

The output is (static constructor called before accessing static data):

#294 – Make All Constructors Private to Prevent Object Creation

If you want to prevent code external to a class from creating instances of that class, you can make all of the constructors of the class private.

In the following example, we have a single Dog constructor, which is private.

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

Because the constructor is private, code outside the Dog class cannot create a new instance of a Dog.

But we can have a static method in the Dog class that can create instances.  Because the code is defined inside the Dog class, it has access to the private constructor.

public class Dog
{
        // code omitted

        public static Dog MakeADog()
        {
            // Use private constructor
            Dog nextDog = new Dog(nameList[nextDogIndex], ageList[nextDogIndex]);

            nextDogIndex = (nextDogIndex == (nameList.Length - 1)) ? 0 : nextDogIndex++;

            return nextDog;
        }

Now if we want a new Dog instance, we can call the MakeADog method.

#293 – You Can Declare a Private Constructor

It’s possible to have one or more instance constructors be private.  A private constructor means that only code internal to the class can construct an instance using that particular combination of parameters.

Below is an example, where we have a public Dog constructor that takes two arguments, but a private one that takes only a name.

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

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

        private Dog(string name)
        {
            Name = name;
        }

A private constructor is typically called from within a static method in the class. For example:

        public static Dog MakeAnOldDog()
        {
            // Use private constructor
            Dog oldDog = new Dog("Rasputin");
            oldDog.Age = 15;

            return oldDog;
        }

#291 – No Default Constructor if You Define any Constructors

If you don’t define any constructors in a class, the compiler automatically generates a default parameterless constructor.  You can then create a new instance of the object without passing any parameters.

            Dog d1 = new Dog();

If you define at least one constructor, the compiler no longer generates a parameterless constructor.

Below, we define a single constructor for Dog, accepting a name parameter.

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

        public Dog(string name)
        {
            Name = name;
            Age = 1;
        }
    }

Now we can define a new instance of Dog by passing in a name parameter.  But we can no longer create a new instance using no parameters.

            Dog d1 = new Dog("Rin Tin Tin");

            // Compiler error: Dog does not contain a constructor
            //   that takes 0 arguments.
            Dog d2 = new Dog();