Table of contents
1.
Introduction
2.
What is Dispose()?
2.1.
Syntax of Dispose()
2.2.
Implementing the Disposal Method  
2.3.
Example of Dispose() in C#
3.
What is Finalize()?
3.1.
Syntax of Finalize()
3.2.
Implementing the Finalize Method  
3.3.
Example of Finalize() in C#
4.
Key Differences between Dispose() and Finalize()
5.
Head-to-Head Comparison between Dispose() and Finalize()
6.
Frequently Asked Questions
6.1.
When should I use Dispose() instead of Finalize()?
6.2.
Can I use both Dispose() and Finalize() together?
6.3.
Why is Finalize() not recommended for managed resources?
7.
Conclusion
Last Updated: Mar 4, 2025
Easy

Finalize() and Dispose() methods in C#

Author Pallavi singh
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

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. 

Finalize() and Dispose() methods in C#

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.

What is Finalize()?

Finalize() is a destructor method in C# that is automatically called by the garbage collector (GC) before reclaiming an object. It is used to clean up unmanaged resources when an object is no longer in use.

Syntax of Finalize()

class ClassName
{
    ~ClassName()
    {
        // Cleanup code here
    }
}

Implementing the Finalize Method  

The `Finalize` method in C is used to clean up unmanaged resources when an object is no longer in use & is being garbage collected. Unlike the `Dispose` method, which is called explicitly by the developer, the `Finalize` method is called automatically by the garbage collector. This makes it a safety net to ensure resources are released even if `Dispose` is not called.  

However, relying solely on the `Finalize` method is not recommended because:  

1. It is non-deterministic, meaning you don’t know exactly when it will be called.  
 

2. It can impact performance because objects with finalizers take longer to be garbage collected.  


To implement the `Finalize` method, you need to define a destructor in your class. In C, the destructor is defined using the `~` symbol.  


For example: 

using System;


public class ResourceManager
{
    // 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.");
    }


    // Destructor (Finalize method)
    ~ResourceManager()
    {
        // Release unmanaged resources
        if (fileHandle != IntPtr.Zero)
        {
            // Simulate releasing the resource
            fileHandle = IntPtr.Zero;
            Console.WriteLine("Resource released by the finalizer.");
        }
    }
}


class Program
{
    static void Main(string[] args)
    {
        // Create an instance of ResourceManager
        var resource = new ResourceManager();


        // Use the resource
        Console.WriteLine("Using the resource...");


        // Let the resource go out of scope
        resource = null;


        // Force garbage collection (for demonstration purposes only)
        GC.Collect();
        GC.WaitForPendingFinalizers(); // Wait for the finalizer to run


        Console.WriteLine("Resource cleanup completed.");
    }
}


In this Code:  

1. Destructor (`~ResourceManager`): The destructor is defined using the `~` symbol. It acts as the `Finalize` method & is called automatically by the garbage collector when the object is no longer in use.  
 

2. Unmanaged Resource Cleanup: Inside the destructor, we release the unmanaged resource (in this case, the `fileHandle`).  
 

3. Garbage Collection: In the `Main` method, we set the `resource` object to `null` to make it eligible for garbage collection. We then call `GC.Collect()` to force garbage collection & `GC.WaitForPendingFinalizers()` to ensure the finalizer runs.  


Key Points to Remember:  

  • The `Finalize` method is not deterministic, so it should not be relied upon for critical resource cleanup.  
     
  • It is always better to use the `Dispose` method for explicit resource management & use the `Finalize` method as a backup.  
     
  • Objects with finalizers take longer to be garbage collected, which can impact performance.  

Example of Finalize() in C#

using System;

class ResourceHolder
{
    public ResourceHolder()
    {
        Console.WriteLine("Resource allocated.");
    }

    ~ResourceHolder()
    {
        Console.WriteLine("Resource cleaned up in Finalize().");
    }
}

class Program
{
    static void Main()
    {
        ResourceHolder obj = new ResourceHolder();
    }
}

 

Output (May not appear immediately due to garbage collection timing)

Resource allocated.
Resource cleaned up in Finalize().

Key Differences between Dispose() and Finalize()

ParametersDispose()Finalize()
ImplementationExplicit (via IDisposable interface)Implicit (destructor method)
Call MechanismManually called by the userAutomatically called by the garbage collector
Resource CleanupImmediateDelayed, depends on garbage collection
PerformanceEfficient, as it releases resources promptlyLess efficient due to garbage collection overhead
Can It Be Overridden?YesYes, but not recommended
Used ForBoth managed and unmanaged resourcesMostly unmanaged resources

Head-to-Head Comparison between Dispose() and Finalize()

1. Calling Mechanism

  • Dispose() needs to be called manually or used within a using statement.
     
  • Finalize() is automatically invoked by the garbage collector.
     

2. Resource Management

  • Dispose() is used to release resources immediately.
     
  • Finalize() waits for the garbage collector to free resources.
     

3. Performance Considerations

  • Dispose() improves performance by freeing resources explicitly.
     
  • Finalize() can lead to performance overhead due to garbage collection delays.
     

4. Implementation Approach

  • Dispose() is implemented via the IDisposable interface.
     
  • Finalize() is implemented using a destructor (~ClassName()).
     

5. Best Practices

  • Prefer Dispose() for timely resource cleanup.
     
  • Use Finalize() only when dealing with unmanaged resources where Dispose() is not an option.

Frequently Asked Questions

When should I use Dispose() instead of Finalize()?

You should use Dispose() when dealing with both managed and unmanaged resources and when you want explicit control over resource cleanup. Finalize() should only be used for unmanaged resources when Dispose() is not available.

Can I use both Dispose() and Finalize() together?

Yes, you can implement both methods together. A common pattern is to call Dispose() inside Finalize() to ensure resource cleanup.

Why is Finalize() not recommended for managed resources?

Finalize() is not recommended for managed resources because it relies on the garbage collector, which introduces unpredictability in resource cleanup. It is also slower than Dispose().

Conclusion

In this article, we discussed the differences between Dispose() and Finalize() in C#, which are used for resource management and garbage collection. The Finalize() method is automatically called by the garbage collector to clean up unmanaged resources, whereas Dispose() is manually implemented through the IDisposable interface for deterministic resource disposal. Understanding these methods helps in efficient memory management and preventing resource leaks in C# applications.

Live masterclass