Difference Between Dispose() and Finalize() in C#

Difference Between Dispose() and Finalize() in C#

In C#, both Dispose() and Finalize() are used to release unmanaged resources (like file handles, database connections, or network sockets), but they differ in how and when they are used.

 

What is Dispose()?

  • Part of the IDisposable interface.
  • Must be called manually by the developer or via a using block.
  • Releases unmanaged resources deterministically (i.e., at a known time).
  • Ideal for cleaning up resources as soon as you're done with them.

Commonly used with: Files, database connections, network streams.

 

What is Finalize()?

  • A special method: ~ClassName() (destructor syntax in C#).
  • Called automatically by the Garbage Collector (GC).
  • Runs non-deterministically—you don’t know exactly when.
  • Typically used as a backup in case Dispose() wasn’t called.

Note: You should avoid using Finalize() unless absolutely necessary because it can slow down garbage collection.

 

Key Differences

Feature

Dispose()

Finalize()

Triggered by

Developer (manual)

Garbage Collector (automatic)

Defined in

IDisposable interface

Destructor (~ClassName())

Execution timing

Deterministic (when called)

Non-deterministic

Resource management

Primary mechanism

Backup mechanism

Performance impact

Efficient

Slower (GC overhead)

Accessibility

Public

Protected

 

Real Example: Dispose() and Finalize() Together

public class FileWriter : IDisposable

{

    private StreamWriter _writer;

    private bool _disposed = false;

 

    public FileWriter(string path)

    {

        _writer = new StreamWriter(path);

    }

 

    public void Write(string text)

    {

        if (_disposed)

            throw new ObjectDisposedException("FileWriter");

 

        _writer.WriteLine(text);

    }

 

    // Dispose method for releasing resources manually

    public void Dispose()

    {

        Dispose(true);

        GC.SuppressFinalize(this); // Prevent Finalize from being called

    }

 

    protected virtual void Dispose(bool disposing)

    {

        if (!_disposed)

        {

            if (disposing)

            {

                // Dispose managed resources

                _writer?.Dispose();

            }

 

            // Clean up unmanaged resources here if any

 

            _disposed = true;

        }

    }

 

    // Finalizer

    ~FileWriter()

    {

        Dispose(false);

    }

}

Usage:

using (var file = new FileWriter("log.txt"))

{

    file.Write("Logging message...");

}

// Dispose is called automatically at the end of the using block

 

Summary

  • Use Dispose() for manual, controlled cleanup of unmanaged resources.
  • Use Finalize() only when necessary as a safety net, and always combine it with Dispose(bool) for proper cleanup patterns.

Best Practice: Always prefer Dispose() with a using block. Implement Finalize() only if unmanaged resources need to be released even when Dispose() wasn’t called.

 

Comments

Popular posts from this blog

Promises in Angular

Mastering Your Angular Workflow: Essential CLI Commands for Efficient Development

Observables in Angular