Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need a finalizer if my class implements IDisposable?

Tags:

c#

.net

c#-3.0

What about below disposable pattern?

using System;
public class MyClass : IDisposable 
{     
    public void Dispose() 
        // Implement IDisposable     
    {
        //just do the cleanup
        GC.SuppressFinalize(this);
    } 

} 

Update

I meant to say, if there are no un-managed resources do I need finalizer? Isn't the above disposable pattern is good enough? Yes, even though users/developers doesn't invoke dispose, doesn't GC invoke dispose by default?

And what about the order in which GC invokes dispose and finalizers?

Please see this question for more details.

In other words, when we have finalizer, why do we call Dispose with false as parameter?


From http://msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2, looks like its always advisable to release unmanaged resources from finalizer and not the managed references.

It's always recommended to release unmanaged resources from Dispose method. I still didn't get the total gist when reading the article.

But if there are no unmanaged resources, the below pattern should work.


According to msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2, msdn.microsoft.com/en-us/library/fs2xkftw.aspx it's recommended to release native resources in finalizer and all of them with dispose(). If dispose() is called explicitly, it can suppress finalizer i.e. if there no native resources, we don't need finalizer.

using System;
public class MyClass : IDisposable 
{ 
    private bool disposed = false;  
    protected virtual void Dispose(bool suppressFinalize) 
    {    
        if (!disposed)
        {
            //Just do the cleanup
            //and release resources
            disposed = true; 
        }
        if (!suppressFinalize)
        {
            GC.SuppressFinalize(this); 
        }
    }
    public void Dispose() 
        // Implement IDisposable     
    {
        Dispose(true);           
    } 
    ~MyClass() // the finalizer
    {     
        Dispose(false);    
    }
} 
like image 817
Dreamer Avatar asked Sep 18 '25 18:09

Dreamer


1 Answers

Because you might have direct references to unmanaged resources (e.g. Windows handles) and you want to release them even if no-one calls Dispose.

This is very rare though - usually you only really have indirect references to unmanaged resources, via other managed types which will have finalizers if they need them.

like image 168
Jon Skeet Avatar answered Sep 21 '25 08:09

Jon Skeet