BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 1.1+

C# Constructors and Finalizers

The fourth article in the C# Object-Oriented Programming tutorial examines constructors and finalizers. These special methods allow an object to be initialised on instantiation and to perform final actions before it is removed from memory.

Parameterised Constructors

The previous example shows the addition of a new constructor to a class. However, this constructor is very limiting as it includes no parameters to control the initialisation process. To enhance the constructor, we can add parameters in the same way as they would be added to any other method. The following constructor adds two parameters so that the height and base-length of the triangle can be specified during instantiation. It set the properties of the class rather than directly setting the private variables to re-use the validation that they provide. Update the constructor with this version.

public Triangle(int height, int baseLength)
{
    Console.WriteLine("Triangle constructor executed");

    this.Height = height;
    this.BaseLength = baseLength;
}

If you try to build or execute the console application you will now receive a compiler error indicating that no constructor is available that accepts zero arguments. This is because the Main method is still trying to use the default constructor. As this has been replaced, the Main method must be adjusted to use the new, parameterised version as follows:

static void Main(string[] args)
{
    Triangle triangle = new Triangle(5,8);

    Console.WriteLine("Height:\t{0}", triangle.Height);
    Console.WriteLine("Base:\t{0}", triangle.BaseLength);
    Console.WriteLine("Area:\t{0}", triangle.Area);
}

/* OUTPUT

Triangle constructor executed
Height: 5
Base:   8
Area:   20

*/

Finalizers

A finalizer is a special member that can be added to a class. It is called automatically when an object is no longer required and is being removed from memory. A finalizer can be useful because it can ensure that all objects of a particular class terminate cleanly. For example, if a class maintains a database connection, the finalizer can be used to ensure that any database transaction is rolled back if it has not been committed and that the database connection is closed when the object is cleaned up.

In other .NET languages, the object class's Finalize method can be overridden to provide the clean-up code. In C#, this is not permitted and a special finalizer syntax is used. This forces the calling of the finalizer of the base class of the object too, by implicitly converting the finalizer statements into the Finalize code below:

protected override void Finalize()
{
    try
    {
        // Finalizer code
    }
    finally
    {
        base.Finalize();
    }
}

Creating a Finalizer

The syntax to create a finalizer is very simple. The class name is prefixed with a tilde character (~). No parameters are permitted as the finalizer cannot be called manually. To add a finalizer to the Triangle class, add the following code:

~Triangle()
{
    Console.WriteLine("Triangle finalizer executed");
}

NB: The finalizer outputs a message only as there is no clean up required for Triangle objects.

Executing the Finalizer

The finalizer is executed automatically when the object is removed from memory. This can be demonstrated by running the console application. The output should be as follows:

Triangle constructor executed
Height: 5
Base:   8
Area:   20
Triangle finalizer executed

NB: Classes that require finalizers should also implement the IDisposable interface.

Garbage Collection

When objects are created they occupy some memory. As memory is a limited resource, it is important that once the objects are no longer required, they are cleaned up and their memory is reclaimed. The .NET framework uses a system of garbage collection to perform this activity automatically so that the developer does not need to control this directly.

The garbage collector periodically checks for objects in memory that are no longer in use and that are referenced by no other objects. It also detects groups of objects that reference each other but as a group have no other remaining references. When detected, the objects' finalizers are executed and the memory utilised is returned to the pool of available memory.

Garbage Collection and Finalizers

The garbage collection system is completely automated and requires little consideration by the C# developer. However, it is important to understand that an object's finalizer is not called immediately that it is falls out of scope. There can be a delay until the garbage collector decides to reclaim the object's memory and it is only at this point that the finalizer is called.

13 October 2007