Reader Level:
ARTICLE

Constructor and Destructors in C#

Posted by Rajesh VS Articles | C# Language October 10, 2001
This detailed article talks about how constructors and destructors work in C# and how to use them in your applications.
  • 1
  • 0
  • 248578

A constructor can be used, where every time an object gets created and if we want some code to be executed automatically. The code that we want to execute must be put in the constructor. The general form of a C# constructor is as follows 

modifier constructor_name (parameters)
{
//constructor body
}

The modifiers can be private,public, protected or internal.The name of a constructor must be the name of the class, where it is defined. A constructor can take zero or more arguments. A constructor with zero arguments (that is no-argument) is known as default constructor. Remember that there is not return type for a constructor. 

The following class contains a constructor, which takes two arguments. 

class Complex
{
private int x;
private int y;
public Complex (int i, int j)
{
x = i;
y = j;
}
public void ShowXY ()
{
Console.WriteLine(x + "i+" + y);
}
}

The following code segment will display 20+i25 on the command prompt.  

Complex c1 = new Complex (20,25);
c1.ShowXY ();
// Displays 20+i25

That is when we create the object of the class Complex, it automatically calls the constructor and initializes its data members x and y. We can say that constructor is mainly used for initializing an object. Even it is possible to do very complicated calculations inside a constructor. The statement inside a constructor can throw exceptions also. 

If we don't provide a constructor with a class, the C# provides a default constructor with an empty body to create the objects of the class. Remember that if we provide our own constructor, C# do not provide the default constructor. 

The complete program is given below

// C# constructor example
// Author: rajeshvs@msn.com
using System;
class Complex
{
private int x;
private int y;
public Complex(int i, int j) // constructor with 2 arguments
{
x = i;
y = j;
}
public void ShowXY()
{
Console.WriteLine(x +"i+" + y);
}
}
class MyClient
{
public static void Main()
{
Complex c1 =
new Complex(20,25);
c1.ShowXY();
}
}

Constructor Overloading 

Just like member functions, constructors can also be overloaded in a class. The overloaded constructor must differ in their number of arguments and/or type of arguments and/or order of arguments. 

The following program shows the overloaded constructors in action. 

// C# constructor overloading
// author: rajeshvs@msn.com
using System;
class Complex
{
public Complex(int i, int j)
{
Console.WriteLine("constructor with 2 integer arguemets");
}
public Complex(double i, double j)
{
Console.WriteLine("constructor with 2 double arguments");
}
public Complex()
{
Console.WriteLine("no argument constructor");
}
}
class MyClient
{
public static void Main()
{
Complex c1 =
new Complex(20,25);// displays 'constructor with 2 integer arguments'
Complex c2 = new Complex(2.5,5.9); // displays 'constructor with 2 double arguments'
Complex c3 = new Complex(); displays 'no argument constructor'
}
}

Private Constructors

We already see that, in C#, constructors can be declared as public, private, protected or internal. When a class declares only private constructors, it is not possible other classes to derive from this class or create an instance of this class. Private constructors are commonly used in classes that contain only static members. However a class can contain both private and public constructor and objects of such classes can also be created, but not by using the private constructor.

The following is a valid program in C# 

// C# constructor both private & public
// Author: rajeshvs@msn.com
using System;
class Complex
{
private Complex(int i, int j)
{
Console.WriteLine("constructor with 2 integer arguments");
}
public Complex()
{
Console.WriteLine("no argument constructor");
}
}
class MyClient
{
public static void Main()
{
Complex c3 =
new Complex();
}
}

However the following program do not compile since it contain only private constructors 

// C# constructor only private. Will show compilation error.
// Author: rajeshvs@msn.com
using System;
class Complex
{
private Complex()
{
Console.WriteLine("no argument constructor");
}
}
class MyClient
{
public static void Main()
{
Complex c3 =
new Complex();
}
}
public void Method1()
{
Console.WriteLine("Method of a non-abstract class");
}
}

Constructor Chaining

The entire above program shows that C# supports constructor overloading. In C#, even one constructor can invoke another constructor in the same class or in the base class of this class. This is what is known as constructor chaining.A special type of syntax is used for constructor chaining as follows. 

// C# constructor chaining
// Author: rajeshvs@msn.com
using System;
class Complex
{
private Complex()
{
Console.Write("1");
}
private Complex(int x):this()
{
Console.Write("2");
}
public Complex(int x, int y):this(10)
{
Console.Write("3");
}
}
class MyClient
{
public static void Main()
{
Complex c =
new Complex(10,20); // Displays 123
}


In the above program the Complex(int x, int y) invokes the Complex(int x) constructor by using a special syntax ':' this(arguments), which in turn invokes the Complex() constructor.

Static Constructors 

The normal constructors, which we explained till now, can be used for the initialization of both static and non-static members. But C# provides a special type of constructor known as static constructor to initialize the static data members when the class is loaded at first. Remember that, just like any other static member functions, static constructors can't access non-static data members directly. 

The name of a static constructor must be the name of the class and even they don't have any return type. The keyword static is used to differentiate the static constructor from the normal constructors. The static constructor can't take any arguments. That means there is only one form of static constructor, without any arguments. In other way it is not possible to overload a static constructor.

We can't use any access modifiers along with a static constructor. 

For example

// C# static constructor
// Author: rajeshvs@msn.com
using System;
class Complex
{
static Complex()
{
Console.WriteLine("static constructor");
}
}
class MyClient
{
public static void Main()
{
Complex c;
Console.WriteLine("RAJESH");
c =
new Complex();
}


The output of the above program is
RAJESH
static constructor 

Note that static constructor is called when the class is loaded at the first time. However we can't predict the exact time and order of static constructor execution. They are called before an instance of the class is created, before a static member is called and before the static constructor of the derived class is called. 

Like non-static constructors, static constructors can't be chained with each other or with other non-static constructors. The static constructor of a base class is not inherited to the derived class. 

Constructors & Inheritance 

Both static and non-static constructors are not inherited to a derived class from a base class. However, a derived class non-static constructor can call a base class non-static constructor by using a special function base(). It is possible to invoke both default and parameterized constructors of the base class from the derived class. If we don't call the base class constructor explicitly, the derived class constructor will call the default constructor of the base class implicitly when an object of the derived class is created. This is shown in the program given below. 

// C# Implicit call of base class default constructor
// Author: rajeshvs@msn.com
using System;
class Base
{
public Base()
{
Console.WriteLine("base constructor");
}
}
class Derived : Base
{
}
class MyClient
{
public static void Main()
{
Derived d1 =
new Derived();//Displays 'base constructor'
}


We can also call a base class constructor explicitly by using base() as shown below. 

// C# Implicit call of base class default constructor
// Author: rajeshvs@msn.com
using System;
class Base
{
public Base()
{
Console.WriteLine("BASE 1");
}
public Base(int x)
{
Console.WriteLine("BASE 2");
}
}
class Derived : Base
{
public Derived():base(10)
{
Console.WriteLine("DERIVED CLASS");
}
}
class MyClient

{
public static void Main()
{
Derived d1 =
new Derived();//Displays 'base constructor'
}
}

This program outputs
BASE2
DERIVED CLASS 

The base() can be used for chaining constructors in a inheritance hierarchy.

Destructors 

The .NET framework has an in built mechanism called Garbage Collection to de-allocate memory occupied by the un-used objects. The destructor implements the statements to be executed during the garbage collection process. A destructor is a function with the same name as the name of the class but starting with the character ~.

Example:

class Complex
{
public Complex()
{
// constructor
}
~Complex()
{
// Destructor
}
}

Remember that a destructor can't have any modifiers like private, public etc. If we declare a destructor with a modifier, the compiler will show an error.Also destructor will come in only one form, without any arguments. There is no parameterized destructor in C#. 

Destructors are invoked automatically and can't be invoked explicitly. An object becomes eligible for garbage collection, when it is no longer used by the active part of the program. Execution of destructor may occur at any time after the instance or object becomes eligible for destruction. 

In C# all classes are implicitly derived from the super base class object. The object class contains one special method, Finalize(), which every class can override. The Garbage Collection mechanism in .NET will call this method prior to the garbage collection of the objects this class. Remember when we provide a destructor in a class, during the compilation time, the compiler automatically generates the Finalize() method. That means that a destructor and overridden Finalize() method can't co-exist in a class. The following code will generate a compilation error because of the above program 

class Complex
{
~Complex()
{
}
protected override void Finaliz()
{
}
}

COMMENT USING

Trending up