Overview

Let's understand class and related concepts to dive deep into the constructors.

Class

The class is a reference type and defines the type of the object. Classes are declared using the class keyword.

//[access modifier] - [class] - [identifier]
public class Customer
{
   // Fields, properties, methods and events go here...
}
Class Declaration

An object is a concrete entity based on a class, and is sometimes referred to as an instance of a class. Objects can be created by using the new keyword followed by the name of the class that the object will be based on.

When the object is created, enough memory is allocated on the managed heap for that specific object, and the variable holds only a reference to the location of said object.

Constructor

Whenever a class or struct is created, its constructor is called. A class or struct may have multiple constructors that take different arguments. Constructors enable the programmer to set default values, limit instantiation, and write code that is flexible and easy to read.

Parameterless Constructors

A constructor that takes no parameters is called a parameterless constructor. Parameterless constructors are invoked whenever an object is instantiated by using the new operator and no arguments are provided to new.

public class Taxi
{
    public bool IsInitialized;
    public Taxi()
    {
        IsInitialized = true;
    }
}

class TestTaxi
{
    static void Main()
    {
        Taxi t = new Taxi();
        Console.WriteLine(t.IsInitialized);
    }
}
Parameterless Constructor

Implicit Default Constructor

C# relies on implicit parameterless constructor to instantiate members to default values if no constructor is provided.

Static Constructors

Parameterless constructors that initializes the static members of the type.

public class Adult : Person
{
   private static int minimumAge;

   public Adult(string lastName, string firstName) : base(lastName, firstName)
   { }

   static Adult()
   {
      minimumAge = 18;
   }

   // Remaining implementation of Adult class.
}
Static Constructor

Remarks

  • A static constructor does not take access modifiers or have parameters.
  • A class or struct can only have one static constructor.
  • Static constructors cannot be inherited or overloaded.
  • A static constructor cannot be called directly and is only meant to be called by the common language runtime (CLR). It is invoked automatically.
  • The user has no control on when the static constructor is executed in the program.
  • A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced. A static constructor will run before an instance constructor. A type's static constructor is called when a static method assigned to an event or a delegate is invoked and not when it is assigned. If static field variable initializers are present in the class of the static constructor, they will be executed in the textual order in which they appear in the class declaration immediately prior to the execution of the static constructor.
  • If you don't provide a static constructor to initialize static fields, all static fields are initialized to their default value as listed in Default values of C# types.
  • If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running. Most commonly, a TypeInitializationException exception is thrown when a static constructor is unable to instantiate a type or for an unhandled exception occurring within a static constructor. For implicit static constructors that are not explicitly defined in source code, troubleshooting may require inspection of the intermediate language (IL) code.
  • The presence of a static constructor prevents the addition of the BeforeFieldInit type attribute. This limits runtime optimization.
  • A field declared as static readonly may only be assigned as part of its declaration or in a static constructor. When an explicit static constructor is not required, initialize static fields at declaration, rather than through a static constructor for better runtime optimization.

Instance Constructors

The constructor is used to initialize the instance. Instance constructors can be inherited and overloaded.

class Coords
{
    public int x, y;

    // constructor
    public Coords()
    {
        x = 0;
        y = 0;
    }
    
    // A constructor with two arguments.
    public Coords(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}
Instance Constructors

We can use the base and this keyword to reuse different constructors.

class Circle : Shape
{
    public Circle(double radius)
        : base(radius, 0)
    {
    }
}
Base keyword for reusing multiple constructors

Private Constructors

This prevents a class from being instatiated. A private constructor is a special instance constructor. It is generally used in classes that contain static members only. If a class has one or more private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class.

class NLog
{
    // Private Constructor:
    private NLog() { }

    public static double e = Math.E;  //2.71828...
}
Private Constructor

Copy Constructors

C# doesn't provide one, the user can write one itself.

class Person
{
    // Copy constructor.
    public Person(Person previousPerson)
    {
        Name = previousPerson.Name;
        Age = previousPerson.Age;
    }

    //// Alternate copy constructor calls the instance constructor.
    //public Person(Person previousPerson)
    //    : this(previousPerson.Name, previousPerson.Age)
    //{
    //}

    // Instance constructor.
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public int Age { get; set; }

    public string Name { get; set; }

    public string Details()
    {
        return Name + " is " + Age.ToString();
    }
}

class TestPerson
{
    static void Main()
    {
        // Create a Person object by using the instance constructor.
        Person person1 = new Person("George", 40);

        // Create another Person object, copying person1.
        Person person2 = new Person(person1);

        // Change each person's age.
        person1.Age = 39;
        person2.Age = 41;

        // Change person2's name.
        person2.Name = "Charles";

        // Show details to verify that the name and age fields are distinct.
        Console.WriteLine(person1.Details());
        Console.WriteLine(person2.Details());

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
// Output:
// George is 39
// Charles is 41
Copy Constructor

References

Classes - C# Programming Guide
Learn about the class types and how to create them
Constructors - C# Programming Guide
A constructor in C# is called when a class or struct is created. Use constructors to set defaults, limit instantiation, and write flexible, easy-to-read code.
Instance Constructors - C# Programming Guide
Instance constructors in C# create and initialize any instance member variables when you use the new expression to create an object of a class.