C# Tutorial

C# String

C# Array

C# Flow Control

C# Class and Object

C# Inheritance

C# Interface

C# Collection

C# Generic

C# File I/O

C# Delegate and Event

C# Exception

C# Process and Thread

C# ADO.NET Database Operations

C# Destructor

In C#, destructors are used to release resources held by an object when it is no longer needed, such as memory, file handles, or network connections. However, it is essential to note that C# has a garbage collector that automatically reclaims memory, so you don't need to worry about memory management in most cases.

In this tutorial, we'll cover how destructors work in C# and how to define and use them properly.

  • Defining a destructor:

A destructor is a special method with the same name as the class, preceded by a tilde (~). It cannot have any parameters, access modifiers, or a return type.

Here's an example of a destructor for a MyClass class:

class MyClass
{
    // Constructor
    public MyClass()
    {
        Console.WriteLine("Constructor called.");
    }

    // Destructor
    ~MyClass()
    {
        Console.WriteLine("Destructor called.");
    }
}
  • When a destructor is called:

The destructor is called automatically when the garbage collector decides to release the memory occupied by the object. Since the garbage collector runs on a separate thread, you cannot predict exactly when the destructor will be called. In most cases, you don't need to worry about when or if the destructor is called.

  • Usage of destructors:

In C#, destructors are rarely used, because the garbage collector takes care of memory management. However, if your class holds other resources, such as file handles or network connections, you might need to release those resources manually.

It is recommended to use the IDisposable interface and the using statement for this purpose, as it provides a deterministic way to release resources. Here's an example of how to use the IDisposable interface:

using System;
using System.IO;

class MyResource : IDisposable
{
    private StreamReader _reader;

    public MyResource(string filePath)
    {
        _reader = new StreamReader(filePath);
    }

    public void Read()
    {
        Console.WriteLine(_reader.ReadToEnd());
    }

    public void Dispose()
    {
        Console.WriteLine("Disposing resources.");
        _reader.Dispose();
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (MyResource resource = new MyResource("file.txt"))
        {
            resource.Read();
        }

        Console.WriteLine("Resource disposed.");
    }
}

In this example, the MyResource class implements the IDisposable interface and defines a Dispose() method that releases the resources (in this case, the StreamReader). The using statement ensures that the Dispose() method is called when the using block is exited, either by completing the block or by encountering an exception.

In conclusion, destructors are not commonly used in C# due to the garbage collector handling memory management. It is recommended to use the IDisposable interface and the using statement for deterministic resource cleanup.

  1. C# destructor example:

    • Description: A destructor in C# is a special method that is automatically called when an object is about to be destroyed. It's used for releasing resources and performing cleanup.
    • Code:
      public class MyClass
      {
          // Destructor
          ~MyClass()
          {
              // Cleanup code
              Console.WriteLine("Destructor called!");
          }
      }
      
  2. How to define a destructor in C#:

    • Description: Defining a destructor involves using the ~ClassName syntax. It is automatically called when the object is garbage collected.
    • Code:
      public class MyClass
      {
          // Destructor
          ~MyClass()
          {
              // Cleanup code
              Console.WriteLine("Destructor called!");
          }
      }
      
  3. Explicitly implementing IDisposable with destructor in C#:

    • Description: Implementing IDisposable allows explicit resource cleanup. The destructor can be used as a failsafe in case the consumer forgets to call Dispose().
    • Code:
      public class MyClass : IDisposable
      {
          // Dispose method
          public void Dispose()
          {
              // Cleanup code
              Console.WriteLine("Dispose called!");
              // Suppress finalization to avoid calling the destructor
              GC.SuppressFinalize(this);
          }
      
          // Destructor
          ~MyClass()
          {
              // Cleanup code
              Console.WriteLine("Destructor called!");
          }
      }