Search code examples
c#.netdispose

c# disposing syntax


I've had to implement Dispose() functionality recently, and have come across 1 line method, 2 line methods and more comprehensive methods.

A 1 line method/functionwould simply call something like "context.Dispose", but the method I picked up was this:

    bool _disposed = false;

    public void Dispose(bool disposing)
    {
        if (!_disposed && disposing)
        {
            _context.Dispose();
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

Is this syntax merely to stop Dispose() being called more than once?


Solution

  • What you've posted is partially the Dispose Pattern. As someone pointed out there should be a corresponding Dispose(false) in a finalizer ("destructor"). The finalizer should be used to dispose of unmanaged resources. If you don't have unmanaged resources to deal with (i.e. you don't have anything to do when disposing is false), you don't need a Dispose(false) and thus don't need a finalizer. This means thatDispose(true) is the only path, so you don't need Dispose (bool) (and thus don't need to implement the Dispose Pattern) and can move it's body into Dispose (and remove the check for disposing) and just implement Dispose. For example:

    public void Dispose()
    {
        _context.Dispose();
    }
    

    Classes that don't implement their own finalizer (destructor) are not put on the finalizer list so there's no need to call GC.SuppressFinalize.

    In general, this is enough if you're creating a class. But, sometimes you can derive from classes that implement this pattern. In which case you should implement support for it in your class (override Dispose(bool) and do the disposing check and Dispose of any managed resources). Since the base class implements IDisposable and calls a virtual Dispose(bool) in its Dispose(), you don't need to implement Dispose() yourself, but you have to call the base's Dispose(bool) in your Dispose(bool). For example:

    protected override void Dispose(bool disposing)
    {
        if(disposing) _context.Dispose();
        base.Dispose(disposing);
    }
    

    If you're calling into the base and it's implemented the Dispose Pattern, then you also don't need to call GC.SuppressFinalize() because it's already doing it.

    You can do the whole disposed thing if you want; I find that it hides multi-dispose bugs though.