Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
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.
