Page Content

Tutorials

C# Destructor: Your Guide To The Resource Management

C# Destructor

A destructor, also known as a finalizer in C#, is a particular member function of a class that is automatically called upon when a class instance is destroyed. Its main function is to clean up any unmanaged resources that the object may have before deleting them from memory.

Here is a thorough breakdown of C# destructors:

Definition and Purpose

The reverse of a constructor is a destructor. When an object is formed, constructors are called to initialize its state and allocate memory; when an object is destroyed, destructors are invoked to release resources.

File handles, network connections, and database connections are examples of non-managed resources that they are intended to release from an object.

Syntax and Rules

  • Although a destructor’s name is exactly the same as that of its class, it is preceded by a tilde (~).
  • Destructors don’t even have a void return type.
  • No parameters can be taken by them.
  • Destructors cannot be used with any of the following access modifiers: protected, internal, private, or public.
  • One destructor is all that a class can have.
  • Destructors cannot be overloaded or inherited.
  • Only classes can use destructors; they cannot be declared in structs.

Automatic Invocation and Garbage Collection

  • Destructors are automatically called by the Common Language Runtime (CLR) through its garbage collector (GC); programmers do not directly call them.
  • When memory allotted for variables is no longer needed, the garbage collector automatically releases the memory.
  • The garbage collector may destroy an object in one of the following situations:
    • At the end of program execution: The program’s connected objects are all destroyed.
    • Implicit calling during execution: In order to find and eliminate unnecessary items, the garbage collector may run if memory fills up.
    • Explicit calling: Garbage collection can be forced by explicitly calling GC.Collect(), however this is generally discouraged owing to performance considerations.
  • The garbage collector decides when destructor calls occur, therefore programmers have no direct control over this.

Relationship with Finalize and Inheritance

  • A C# destructor implicitly invokes the underlying class’s Finalize function. In this case, every instance in the inheritance chain has a recursive call to the Finalize method.
  • The most-derived class calls Finalize first, followed by the least-derived (base) class, which is the order in which destructors are executed effectively.

Best Practices

Implementing the IDisposable interface and its Dispose() method for explicit resource release is generally advised for managing unmanaged resources. If the destructor was not called, it then acts as a safety measure to clear up resources.

The garbage collector must conduct extra work and performance is needlessly lost when empty destructors are utilised since they add an entry to the Finalise queue.

Code Examples: Basic Destructor Example 

An Example of a Basic Destructor The constructor and destructor of a basic class are shown in this example, along with the times at which they are called.

using System;
namespace DestructorExample
{
    class Line
    {
        private double length;
        // Constructor
        public Line()
        {
            Console.WriteLine("Object is being created (Constructor called)"); 
        }
        // Destructor
        ~Line() 
        {
            Console.WriteLine("Object is being deleted (Destructor called)"); 
        }
        public void SetLength(double len)
        {
            length = len;
        }
        public double GetLength()
        {
            return length;
        }
        static void Main(string[] args)
        {
            Line line = new Line(); // Object created, constructor called 
            line.SetLength(6.0);
            Console.WriteLine("Length of line : {0}", line.GetLength()); 
            // The object 'line' becomes eligible for garbage collection here
            // The destructor will be called automatically when the GC runs,
            // typically when the program exits or memory is low.
        }
    }
}

Output

Object is being created (Constructor called)
Length of line : 6
Object is being deleted (Destructor called)

Explanation: When new Line() is used, the constructor of the Line object is immediately called. When the Main method is finished and the program leaves, the garbage collector calls the destructor ~Line() to reclaim the line object, which is no longer available.

Example: Destructors in an Inheritance Chain

In a chain of inheritance, destroyers In an inheritance hierarchy, this example shows the sequence in which destructors are called.

using System;
namespace InheritanceDestructors
{
    class First
    {
        ~First() // Destructor for the base class
        {
            System.Console.WriteLine("First's destructor is called"); 
        }
    }
    class Second : First // Second inherits from First
    {
        ~Second() // Destructor for the derived class 'Second'
        {
            System.Console.WriteLine("Second's destructor is called"); 
        }
    }
    class Third : Second // Third inherits from Second
    {
        ~Third() // Destructor for the most derived class 'Third'
        {
            System.Console.WriteLine("Third's destructor is called"); 
        }
    }
    class TestDestructors
    {
        static void Main()
        {
            Third t = new Third(); // Create an instance of the most derived class 
            // At this point, the object 't' is created.
            // When 't' goes out of scope and becomes eligible for GC,
            // the destructors will be invoked.
            // We can explicitly suggest GC to run for demonstration purposes
            // (though not recommended in production code)
            GC.Collect(); // Force garbage collection for demonstration 
            GC.WaitForPendingFinalizers(); // Wait for finalizers to complete
        }
    }
}

Output

Third's destructor is called
Second's destructor is called
First's destructor is called

Explanation: Destructors are called in a particular order when t (an instance of Third) qualifies for garbage collection: from the most-derived class (Third) to the least-derived base class (First). This is so that a correct cleanup chain is ensured, as each destructor implicitly calls the Finalise method of its immediate base class.

You can also read C# Constructors Types: Default, Parameterized, Copy & Static

Agarapu Geetha
Agarapu Geetha
My name is Agarapu Geetha, a B.Com graduate with a strong passion for technology and innovation. I work as a content writer at Govindhtech, where I dedicate myself to exploring and publishing the latest updates in the world of tech.
Index