What are finalizers in C#?

Finalizers in C# are special methods that perform cleanup when an object is being destroyed by the garbage collector. They provide a way to release unmanaged resources before the object is removed from memory.

Syntax

Following is the syntax for declaring a finalizer −

~ClassName() {
   // cleanup code here
}

The finalizer declaration uses a tilde (~) followed by the class name with no parameters or access modifiers.

Key Rules

  • Only one finalizer is allowed per class.

  • Finalizers cannot be inherited or overloaded.

  • A finalizer cannot have parameters or access modifiers.

  • Finalizers are invoked automatically by the garbage collector.

  • You cannot call a finalizer directly from your code.

Finalizer Execution Flow Object Created Out of Scope Finalizer Called Garbage collector determines when to call finalizers - timing is unpredictable Use IDisposable for deterministic cleanup

Using Finalizers for Resource Cleanup

Example

using System;

class FileManager {
   private string fileName;

   public FileManager(string name) {
      fileName = name;
      Console.WriteLine("FileManager created for: " + fileName);
   }

   ~FileManager() {
      Console.WriteLine("Finalizer called for: " + fileName);
      Console.WriteLine("Releasing file resources...");
   }

   public void ProcessFile() {
      Console.WriteLine("Processing file: " + fileName);
   }
}

class Program {
   public static void Main() {
      FileManager fm1 = new FileManager("data.txt");
      fm1.ProcessFile();

      FileManager fm2 = new FileManager("config.xml");
      fm2.ProcessFile();

      fm1 = null;
      fm2 = null;

      Console.WriteLine("Forcing garbage collection...");
      GC.Collect();
      GC.WaitForPendingFinalizers();
      Console.WriteLine("Program ending");
   }
}

The output of the above code is −

FileManager created for: data.txt
Processing file: data.txt
FileManager created for: config.xml
Processing file: config.xml
Forcing garbage collection...
Finalizer called for: config.xml
Releasing file resources...
Finalizer called for: data.txt
Releasing file resources...
Program ending

Finalizers vs IDisposable

While finalizers provide automatic cleanup, they have limitations. The IDisposable interface provides deterministic cleanup through the Dispose() method −

Finalizers IDisposable
Called automatically by garbage collector Called explicitly by developer using Dispose()
Unpredictable timing Deterministic timing
Cannot be called directly Can be called directly or with using statement
Impacts garbage collection performance More efficient for resource cleanup

Example with IDisposable Pattern

using System;

class ResourceManager : IDisposable {
   private bool disposed = false;

   public ResourceManager() {
      Console.WriteLine("ResourceManager created");
   }

   public void DoWork() {
      if (disposed) {
         throw new ObjectDisposedException("ResourceManager");
      }
      Console.WriteLine("Working with resources...");
   }

   public void Dispose() {
      if (!disposed) {
         Console.WriteLine("Dispose called - cleaning up resources");
         disposed = true;
         GC.SuppressFinalize(this);
      }
   }

   ~ResourceManager() {
      Console.WriteLine("Finalizer called - backup cleanup");
   }
}

class Program {
   public static void Main() {
      using (ResourceManager rm = new ResourceManager()) {
         rm.DoWork();
      }
      Console.WriteLine("Program ending");
   }
}

The output of the above code is −

ResourceManager created
Working with resources...
Dispose called - cleaning up resources
Program ending

Conclusion

Finalizers in C# provide automatic cleanup when objects are destroyed by the garbage collector, but their execution timing is unpredictable. For deterministic resource cleanup, implement the IDisposable interface instead, which allows explicit control over when resources are released.

Updated on: 2026-03-17T07:04:35+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements