IDisposable is an interface defined in the System namespace that contains a single method, Dispose.
The purpose of this interface is to provide an explicit way to release unmanaged resources deterministically, ensuring these resources are freed as soon as they are no longer needed.
In C#, the Garbage Collector is responsible for freeing the memory allocated to objects once they are no longer needed. However, there are unmanaged resources, such as database connections, files, sockets, etc., that are not automatically managed by the Garbage Collector.
If not properly released, these resources can cause memory leaks and other performance issues. Implementing IDisposable allows developers to release these resources explicitly and in a controlled manner.
The IDisposable interface provides a way to release these unmanaged resources explicitly, allowing for better control over resource management in an application.
IDisposable Interface
The IDisposable interface is defined as follows:
namespace System
{
public interface IDisposable
{
void Dispose();
}
}
When a class implements IDisposable, it commits to providing an implementation of the Dispose method, in which unmanaged resources will be released.
Basic Example
Suppose we have a class that handles a file. We want to ensure the file is closed correctly when it is no longer needed.
We implement IDisposable to achieve this:
public class FileHandler : IDisposable
{
private FileStream _file;
public FileHandler(string path)
{
_file = new FileStream(path, FileMode.OpenOrCreate);
}
public void Write(string message)
{
byte[] info = new UTF8Encoding(true).GetBytes(message);
_file.Write(info, 0, info.Length);
}
public void Dispose()
{
_file?.Close();
_file?.Dispose();
}
}
In this example, the Dispose method closes and releases the FileStream used by the FileHandler class.
Usage with using
To simplify calling Dispose, C# provides the using statement, which ensures that Dispose is called automatically at the end of the using block:
using (var handler = new FileHandler("file_path.txt"))
{
handler.Write("Hello, world!");
}
This code guarantees that the Dispose method of FileHandler is called automatically, even if an exception occurs inside the using block.
Using GC.SuppressFinalize
When Dispose is called explicitly, it is good practice to use GC.SuppressFinalize to prevent the garbage collector from calling the destructor, thus optimizing performance.
