What is IDisposable and the Dispose pattern?
Quick Answer
IDisposable defines Dispose(), a place to release resources the garbage collector doesn't manage — file handles, DB connections, sockets, native memory. You call it deterministically with using. The full Dispose pattern adds a finalizer as a safety net for the rare case where you hold a raw OS handle directly.
IDisposable is how a class says “I hold something the garbage collector won't clean up — call Dispose when you're done.” That's file handles, database connections, sockets. I call it with a using statement so it runs deterministically at the end of the scope. If my class just wraps other disposables I only need to dispose those. The full pattern with a finalizer is for when I hold a raw OS handle directly — Dispose calls GC.SuppressFinalize so the finalizer is skipped if I disposed properly — but honestly I'd use SafeHandle and never write a finalizer myself.
The GC frees managed memory but has no idea about a Win32 handle. If you don't release it, it leaks until the process exits (or a finalizer eventually runs, non-deterministically).
Simple case — you only wrap other IDisposable objects: implement Dispose() and dispose your fields. No finalizer needed.
Full pattern — you hold a raw handle:
Dispose()→ callsDispose(true)thenGC.SuppressFinalize(this).protected virtual void Dispose(bool disposing)→ ifdisposing, release managed resources too; always release unmanaged ones.- A finalizer
~MyClass()→ callsDispose(false)as a backstop.
In practice, prefer SafeHandle (it has the finalizer built in) so you never write one. using var x = ...; and await using (for IAsyncDisposable) call Dispose at the end of scope.
public sealed class ReportWriter : IDisposable
{
private readonly StreamWriter _writer;
public ReportWriter(string path) => _writer = new StreamWriter(path);
public void Write(string line) => _writer.WriteLine(line);
public void Dispose() => _writer.Dispose();
}
using var writer = new ReportWriter("out.txt");
writer.Write("done"); // Dispose runs at end of scope