Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disposing the members that implement IDisposable

In my Dispose methods (like the one below), everytime i want to call someObj.Dispose() i also have a check for someObj!=null.

Is that because of bad design on my part? Is their a cleaner way to ascertain that Dispose of all the members (implementing IDisposable) being used in an object is called without having a risk of NullReference exception ?

protected void Dispose(bool disposing)
        {
            if (disposing)
            {
               if (_splitTradePopupManager != null)
                {
                    _splitTradePopupManager.Dispose();
                }
             }
        }

Thanks for your interest.

like image 216
Manish Basantani Avatar asked Jun 11 '10 12:06

Manish Basantani


2 Answers

I like @Dan Tao's solution, but it's much better as an extension method, imo:

public static void SafeDispose(this IDisposable obj)
{
    if (obj != null)
        obj.Dispose();
}

Now you can just call member.SafeDispose() on any IDisposable in your program without worry. :)

like image 89
tzaman Avatar answered Oct 06 '22 20:10

tzaman


Maybe someone else can chime in on this, but I don't personally think it's a design flaw -- just the safest way to do it.

That said, nothing's stopping you from wrapping your null check and Dispose call in a convenient method:

private void DisposeMember(IDisposable member)
{
    if (member != null)
        member.Dispose();
}

Then your Dispose method could look a bit cleaner:

protected void Dispose(bool disposing)
{
    if (disposing)
    {
        DisposeMember(_splitTradePopupManager);
        DisposeMember(_disposableMember2);
        DisposeMember(_disposableMember3);
    }
}

As an added bonus, this also resolves a potential race condition in your original code. If running in a multithreaded context, the if (_field != null) _field.Dispose() pattern can result in a NullReferenceException when _field is set to null between the check and the disposal (rare, but possible). Passing _field as an argument to a method such as DisposeMember copies the reference to a local variable in the method, eliminating this possibility, unlikely as it is.

like image 42
Dan Tao Avatar answered Oct 06 '22 19:10

Dan Tao