Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
What is the difference between Finalize and Dispose in C#?
The Finalize and Dispose methods in C# are both used for cleaning up resources, but they work differently and serve distinct purposes in memory management. Understanding their differences is crucial for proper resource management in .NET applications.
Finalize Method
The Finalize() method is called automatically by the Garbage Collector before an object eligible for collection is reclaimed. The Garbage Collector takes responsibility for deallocating memory for unreferenced objects. This method is called at some point after there are no longer valid references to that object in memory.
The framework does not guarantee when this will happen. While we can force garbage collection, it will hurt program performance. Finalize() belongs to the Object class and is called by the runtime automatically.
Example
using System;
namespace DemoApplication {
public class Demo {
~Demo() {
Console.WriteLine("Finalize called");
}
}
public class Program {
public static void Main() {
Demo obj = new Demo();
obj = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
The output of the above code is −
Finalize called
Dispose Method
Some resources like window handles, database connections, network connections, and files cannot be collected by the Garbage Collector. To explicitly release specific objects, it's best to implement IDisposable and override the Dispose() method.
The Dispose() method is not called automatically − we must explicitly call it from client applications when an object is no longer needed. Dispose() can be called even if other references to the object are alive.
Example
using System;
namespace DemoApplication {
public class Demo : IDisposable {
private bool disposed = false;
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (!disposed) {
if (disposing) {
// Clean up managed objects
Console.WriteLine("Managed resources cleaned up");
}
// Clean up unmanaged objects
Console.WriteLine("Unmanaged resources cleaned up");
disposed = true;
}
}
~Demo() {
Dispose(false);
}
}
public class Program {
public static void Main() {
using (Demo obj = new Demo()) {
// Object is used here
} // Dispose is called automatically
}
}
}
The output of the above code is −
Managed resources cleaned up Unmanaged resources cleaned up
Key Differences
| Aspect | Finalize | Dispose |
|---|---|---|
| Called By | Garbage Collector automatically | Developer explicitly |
| Timing | Non-deterministic (when GC runs) | Deterministic (when called) |
| Performance | Slower (objects live longer) | Faster (immediate cleanup) |
| Implementation | Destructor syntax (~ClassName) | IDisposable interface |
Best Practices
Microsoft recommends implementing both Dispose and Finalize when working with unmanaged resources. The Finalize implementation ensures resources are still released when the object is garbage collected, even if a developer neglects to call the Dispose method explicitly.
Always use the using statement or explicitly call Dispose() for objects implementing IDisposable to ensure immediate resource cleanup and better performance.
Conclusion
Finalize is called automatically by the Garbage Collector for cleanup when objects are collected, while Dispose must be called explicitly for immediate resource cleanup. Implement both for robust resource management, with Dispose providing deterministic cleanup and Finalize serving as a safety net.
