Introduction
Finalize() and Dispose() are two important methods in C# used for resource management. The Finalize() method is automatically called by the Garbage Collector (GC) before an object is destroyed and is mainly used for cleaning up unmanaged resources. In contrast, Dispose() is a manual method, part of the IDisposable interface, allowing developers to explicitly release unmanaged resources.

In this article, we will discuss what Dispose() and Finalize() methods are, their differences, and when to use them with proper examples.
What is Dispose()?
Dispose() is a method defined in the IDisposable interface, used to release unmanaged resources explicitly. It is usually called when an object is no longer needed to free up resources immediately rather than waiting for the garbage collector.
Syntax of Dispose()
public interface IDisposable
{
void Dispose();
}
The Dispose() method is called automatically when the using statement ends, ensuring that the resources are released promptly.
Implementing the Disposal Method
The `Dispose` method is part of the `IDisposable` interface in C. It is used to explicitly release unmanaged resources like file handles, database connections, or network sockets. Unlike `Finalize`, which is called automatically by the garbage collector, `Dispose` gives developers control over when resources are released.
To implement the `Dispose` method, you need to follow these steps:
1. Implement the `IDisposable` interface in your class.
2. Define the `Dispose` method to release resources.
3. Use a boolean flag to ensure resources are not disposed of more than once.
4. Optionally, provide a finalizer (`Finalize` method) as a safety net in case `Dispose` is not called.
For example:
using System;
public class ResourceManager : IDisposable
{
// Flag to check if the object has already been disposed
private bool disposed = false;
// Example of an unmanaged resource (e.g., a file handle)
private IntPtr fileHandle;
// Constructor to initialize the resource
public ResourceManager()
{
// Simulate acquiring an unmanaged resource
fileHandle = new IntPtr(100);
Console.WriteLine("Resource acquired.");
}
// Public Dispose method
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); // Prevent the finalizer from running
}
// Protected Dispose method to handle actual cleanup
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Release managed resources (if any)
}
// Release unmanaged resources
if (fileHandle != IntPtr.Zero)
{
// Simulate releasing the resource
fileHandle = IntPtr.Zero;
Console.WriteLine("Resource released.");
}
disposed = true;
}
}
// Finalizer (safety net)
~ResourceManager()
{
Dispose(false);
}
}
class Program
{
static void Main(string[] args)
{
// Using the ResourceManager with Dispose
using (var resource = new ResourceManager())
{
// Use the resource
Console.WriteLine("Using the resource...");
} // Dispose is called automatically here
// Without using block (manual disposal)
var resource2 = new ResourceManager();
resource2.Dispose(); // Explicitly call Dispose
}
}
In this Code:
1. `IDisposable` Interface: The class `ResourceManager` implements the `IDisposable` interface, which requires the `Dispose` method.
2. `Dispose` Method: The public `Dispose` method calls the protected `Dispose(bool)` method with `true` to indicate that the disposal is explicit. It also calls `GC.SuppressFinalize(this)` to prevent the garbage collector from calling the finalizer.
3. Protected `Dispose(bool)` Method: This method handles the actual cleanup. It checks if the object has already been disposed & releases unmanaged resources.
4. Finalizer: The finalizer (`~ResourceManager`) acts as a safety net. It calls `Dispose(false)` to ensure resources are released even if `Dispose` is not called explicitly.
5. Using Block: The `using` block ensures that `Dispose` is called automatically when the block ends.
This implementation ensures that resources are released properly & prevents memory leaks.
Example of Dispose() in C#
using System;
using System.IO;
class FileManager : IDisposable
{
private FileStream fileStream;
public FileManager(string filePath)
{
fileStream = new FileStream(filePath, FileMode.OpenOrCreate);
}
public void WriteData(string data)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data);
fileStream.Write(bytes, 0, bytes.Length);
}
public void Dispose()
{
if (fileStream != null)
{
fileStream.Close();
fileStream.Dispose();
Console.WriteLine("File stream closed and disposed.");
}
}
}
class Program
{
static void Main()
{
using (FileManager file = new FileManager("test.txt"))
{
file.WriteData("Hello, World!");
} // Dispose() is automatically called at the end of using block.
}
}
Output
File stream closed and disposed.