Dispose and Finalize in C#


In this article we are going to discuss Dispose and Finalize in C#. There are many blogs, articles are available on the internet regarding Dispose and Finalize but in this particular article I will try to explain to you with as much as simplest and realistic examples so you can get a clear idea of the Dispose and Finalize use in C#.

In C#, both Dispose and Finalize are mechanisms used for resource cleanup, but they serve different purposes and have different use cases.

1. Dispose

The Dispose method is part of the IDisposable interface and is used for deterministic cleanup of unmanaged resources. Implemented by classes managing unmanaged resources and called explicitly or implicitly (e.g., via a using statement).

Automatically Disposing of Resources

Use the using statement to ensure Dispose is called automatically.

using (var resourceHolder = new ResourceHolder())
{
    // Use resourceHolder here.
}
// resourceHolder.Dispose() is automatically called at the end of the using block.

In this example, the using statement ensures that Dispose is called automaically.

Manually Disposing of Resources

Even though the GC manages memory automatically, certain resources need explicit cleanup. This is where the IDisposable interface and the Dispose method come into play.

IDisposable Interface

Classes that use unmanaged resources should implement the IDisposable interface. This interface contains a single method, Dispose, which should release all resources held by the object.

Dispose Method

The Dispose method is called to release unmanaged resources deterministically.

Implementing IDisposable

Here's an example of a class implementing IDisposable.

public class ResourceHolder : IDisposable
{
    private bool disposed = false;
    private IntPtr unmanagedResource;
    private StreamReader managedResource;

    public ResourceHolder()
    {
        unmanagedResource = // allocate unmanaged resource
        managedResource = new StreamReader("file.txt");
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            managedResource?.Dispose();
        }

        if (unmanagedResource != IntPtr.Zero)
        {
            // Free unmanaged resource
            unmanagedResource = IntPtr.Zero;
        }

        disposed = true;
    }

    ~ResourceHolder()
    {
        Dispose(false);
    }
}

2. Finalize Method

The Finalize method is a special method provided by the Object class and is called by the garbage collector before an object is reclaimed. It is used to clean up unmanaged resources if the Dispose method was not called.

Key Characteristics

  1. Automatic Cleanup - Called by the garbage collector, not the developer.
  2. Non-Deterministic - There is no guarantee when (or even if) the Finalize method will be called.
  3. Unmanaged Resources - Typically used to release unmanaged resources.
  4. Performance Cost - Finalization has a performance cost because it requires additional GC cycles.

Example

public class ResourceHolder
{
    private IntPtr unmanagedResource;

    public ResourceHolder()
    {
        unmanagedResource = // allocate unmanaged resource
    }

    ~ResourceHolder()
    {
        if (unmanagedResource != IntPtr.Zero)
        {
            // Free unmanaged resource
            unmanagedResource = IntPtr.Zero;
        }
    }
}

Next