Monday, May 10, 2021

C# Constructors

CONSTRUCTOR & ITS TYPES
A constructor is a class member which is used to initialize the fields of the class. The fields of the class can be static or non-static. To initialize a static field, static constructor is needed and no access specifier can be specified with static constructor. A non-static constructor initializes the non-static fields of the class and access specifier can be specified with non-static constructor. 

A non-static constructor constructs object of a class with default or any valid arbitrary parameterized values for its fields. 

When we say that "A constructor constructs object", then as a verb (constructs) or behavior it implies to a special method which initializes the state of the fields of the object but as noun (constructor) it implies that a constructor is a class member. Therefore, constructor is a member method of class but at the same time, it is not method in normal sense. We can say that constructor is a special kind of method. This point is explained later. 

The initial state of the object is determined by a constructor. A constructor is therefore the primal behavior of a class which decides the initial states (values of the fields) of an object. It is primal in the sense that even if a constructor is not explicitly declared in the class, default constructor is invoked to initialize the fields of the class. Such behavior of a class can be overloaded by using different parameterized constructors. 

As a non-static constructor, it can create different objects in different memory locations in the heap. So, creating more instances occupies more memory locations but static constructor creates just a single memory location at the heap and can be used by all the objects. 

Some facts about constructor are as follows:
  1. A constructor is invoked only once when an instance of the class is created to initialize the fields of object with the default values of the fields.
  2. A constructor has no explicit return type as per the syntax.
  3. The name of a constructor must be the name of the class.
  4. A constructor is a special method for special purpose
NOTE: Initializing data is the starting point of implementing business logic (i.e. data manipulation and transformation). It is crucial in programming and so constructor plays very important role in OOP.


Look at the below examples to understand the above facts.

using System;

namespace ConsoleConstructors

{

    class First

    {

        int NumDefault;

        private int NumPrivate;

        protected int NumProtected;

        internal int NumInternal;

        public int NumPublic;

 

        public void Initialize()

        {

            //explicit initialization

            this.NumDefault = 1;

            this.NumPrivate = 2;

            this.NumProtected = 3;

            this.NumInternal = 4;

            this.NumPublic = 5;

            Console.WriteLine(NumDefault);

            Console.WriteLine(NumPrivate);

            Console.WriteLine(NumProtected);

            Console.WriteLine(NumInternal);

            Console.WriteLine(NumPublic);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            new First().Initialize();

            Console.ReadKey();

        }

    }

}

Now, what if the fields are not initialized as shown below. The output will be the default values of the fields as illustrated below.

using System;

namespace ConsoleConstructors

{

    class First

    {

        int NumDefault;

        private int NumPrivate;

        protected int NumProtected;

        internal int NumInternal;

        public int NumPublic;

 

        public void Initialize()

        {

            //implicit initialization

            Console.WriteLine(NumDefault); //output 0

            Console.WriteLine(NumPrivate); //output 0

            Console.WriteLine(NumProtected); //output 0

            Console.WriteLine(NumInternal); //output 0

            Console.WriteLine(NumPublic); //output 0

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            new First().Initialize();

            Console.ReadKey();

        }

    }

}

Now, question arises which method does the initialization of the fields? The answer is it is done by the default constructor. The fields are initialized with their default values. This is why such constructor is called default constructor. A default constructor is always parameter-less. An explicit parameter-less constructor should not be called default constrictor as it is not necessary that the fields will be initialized with default values. This is shown below.

using System;

namespace ConsoleConstructors

{

    class First

    {

        int NumDefault;

        private int NumPrivate;

        protected int NumProtected;

        internal int NumInternal;

        public int NumPublic;

 

        public First() //name of constructor is always the name of its class

        {

            //explicit initianlization using constructor

            this.NumDefault = 1;

            this.NumPrivate = 2;

            this.NumProtected = 3;

            this.NumInternal = 4;

            this.NumPublic = 5;

        }

        public void Display()

        {

            Console.WriteLine(this.NumDefault);

            Console.WriteLine(this.NumPrivate);

            Console.WriteLine(this.NumProtected);

            Console.WriteLine(this.NumInternal);

            Console.WriteLine(this.NumPublic);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            new First().Display();

            Console.ReadKey();

        }

    }

}

Note that in the above example, the initialization is hard coded and lacks flexibility. To provide any arbitrary value to the fields, we use parameterized constructors. This is illustrated below.

Example of Parameterized Constructors

using System;

namespace ConsoleConstructors

{

    class First

    {

        int NumDefault;

        private int NumPrivate;

        protected int NumProtected;

        internal int NumInternal;

        public int NumPublic;

 

        //parameterized constructor

        public First(int num1, int num2, int num3, int num4, int num5)

        {

            //explicit initianlization using constructor

            this.NumDefault = num1;

            this.NumPrivate = num2;

            this.NumProtected = num3;

            this.NumInternal = num4;

            this.NumPublic = num5;

        }

        public void Display()

        {

            Console.WriteLine(this.NumDefault);

            Console.WriteLine(this.NumPrivate);

            Console.WriteLine(this.NumProtected);

            Console.WriteLine(this.NumInternal);

            Console.WriteLine(this.NumPublic);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            new First(2,4,5,6,8).Display();

            Console.ReadKey();

        }

    }

}

Differences Between Constructor & Method

So, we find from above illustration that a constructor plays the role of method to initialize the member fields of a class. But then what are the differences between a constructor and a method? This is pointed below.

  1. A constructor is invoked only once when an instance of the class is created to initialize the fields of object with the default values of the fields. But a method can be invoked many times after object creation whenever required.
  2. A constructor has no explicit return type as per the syntax. A method has explicit return type and is part of the signature of the method.
  3. The name of a constructor must be the name of the class but a method can have any arbitrary name as per the naming convention of an identifier.
  4. Looking at the above points, we can say that a constructor is a special method for special purpose.

STATIC CONSTRUCTOR
  1. A static constructor is used to initialize static fields.
  2. A static constructor is invoked before non-static constructor
  3. A static constructor must be without access modifier. 
  4. A static constructor must be without parameter i.e. a static parameter is always parameter-less constructor.
Static constructor has no kind of access modifier. Why?
Static constructor is always parameter-less. Why?
When we talk about access modifier, we should think about a few aspects of access modifier. First, who will access, second, what will be accessed and third, why will be accessed.
A static constructor is used to initialize static fields but such initialization occurs before object initialization. So, no object has any purpose to access static constructor, as an object accesses a non-static constructor for its initialization. Thus, it becomes meaningless to specify the access modifier with a static constructor. Similar logic holds for explaining that a static constructor is always parameter-less. Why is a parameter used? Parameters are used to provide distinct behaviors to objects as methods. Parameterized constructors provide distinct behavior for initialization of objects. At class level, no such distinct behaviors are expected. It must be the same for all objects. Therefore, a static constructor is always parameter-less.

If we try to pass argument or parameter to a static constructor, the compiler will complain. 










Similarly, if we  try to provide any access modifier modifier to static constructor, the compile-time exception will occur.



Example to illustrate that static field is initialized with static constructor.

using System;

namespace ConsoleStaticClass

{

    class Test

    {

        static int x; //static field

        int y;

       

        static Test()//static field initialization using static constructor

        {//A static constructor must be parameter-less, because parameterized constructor is                 always invoked by an object

            x = 100;

        }

        public Test(int d) //non-static constructor to initialize non-static field

        {

            this.y = d;

        }

        public void Display()

        {

            Console.WriteLine("Static field: {0}",x);

            Console.WriteLine("Non-static field: {0}",y);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Test t = new Test(200);

            t.Display();

            Console.ReadKey();

        }

    }

}


Example to illustrate that static constructor is invoked before non-static constructor. 

using System;

namespace ConsoleStaticConstructorFirst

{

    class First

    {

        static int x;

        int y;

        static First()

        {

            x = 10;

            Console.WriteLine("Inside Static Constructor");

        }

        public First()

        {

            this.y = 20;

            Console.WriteLine("Inside Non-static Constructor");

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            First f = new First();

            Console.ReadKey();

        }

    }

}

OUTPUT

Inside Static Constructor

Inside Non-static Constructor


BASE Vs. DERIVED: ORDER OF CONSTRUCTORS CALL

A constructor of derived class runs after the execution of the constructor of its immediate parent class. This fact is illustrated in the following example.

using System;

namespace ConsoleConstructorsRunOrder

{

    class First

    {

        public First()

        {

            Console.WriteLine("Inside First Constructor");

        }

    }

    class Second : First

    { // NOTE The explicit call of parent class constructor using base keyword is not required if the parent class constructor is parameter-less. We could have omit the :base() in following line.

        public Second():base()

        {

            Console.WriteLine("Inside Second Constructor");

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Second s1 = new Second();

            Console.ReadKey();

        }

    }

}

OUTPUT:

Inside First Constructor

Inside Second Constructor


The explicit call of parent class constructor using base keyword is not required if the parent class constructor is parameter-less. But in case of parameterized base class constructor call, the :base(parameter-list) in mandatory. This fact is illustrated in the following example.

using System;

namespace ConsoleConstructorsRunOrder

{

    class First

    {

        int x;

        public First(int num1)

        {

            this.x = num1;

            Console.WriteLine("Inside First Constructor");

        }

        public void ShowFirst()

        {

            Console.WriteLine(this.x);

        }

    }

    class Second : First

    {

        int y;

        /*

        derived class cannot automatically inherit the constructor of the base class

        rather derived class invokes the base class constructor by keyword base

        after derived class constructor, we write :base() to invoke the base class

        constructor as shown below

        */    

        public Second(int num2):base(9)

        {

            this.y = num2;

            Console.WriteLine("Inside Second Constructor");

        }

        public void ShowSecond()

        {

            Console.WriteLine(this.y);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            First f1 = new First(5);

            Second s1 = new Second(20);

            f1.ShowFirst();//5

            s1.ShowFirst();//9

            s1.ShowSecond();//20

            Console.ReadKey();

        }

    }

}

OUTPUT:

Inside First Constructor

Inside First Constructor

Inside Second Constructor

5

9

20


Related Topics 

Constructor Chaining 

Private Constructor

Copy Constructor




No comments:

Post a Comment

Hot Topics