Question

I am working on a project where a certain class hierarchy implements IDisposable.

Some of the classes also implement a Finalize method ( ~MyClass() )

In general it looks something like this:

public class BaseClass : IDisposable
{
}

public class SomeClass : BaseClass
{
    ~SomeClass()
    {
        Dispose();
    }

    Dispose()
    {
        // Do some stuff.
        base.Dispose();
    }
}

public class AnoterClass : SomeClass
{
    ~AnoterClass()
    {
        Dispose();
    }

    Dispose()
    {
        // Do some stuff.
        base.Dispose();
    }
}

I'd like to know what is the proper way of handling calls to Dispose, as it seems that these objects are being disposed by calling Dispose(), and later on crash since the Finalize method is called.

Is it best to keep a flag at the lowest class in the hierarchy (protected bool disposed), and check that in every level of the class hierarchy?

I find that every possible solution requires some code duplication, which is not what i'm after.

Was it helpful?

Solution

You need to suppress finalization if you are manually disposing of your objects.

The pattern to follow is here

Edit:

I think you only need to implement at a particular level of class hierarchy if you have something new to dispose at that level, otherwise I believe that the disposal in the base class will do everything that you need. If your implementation in any particular class just calls base.Dispose(disposing) then it is not needed, if it has to do some clean uop, then call base.Dispose() then you need it.

Having a protected flag as you suggest should be fine.

OTHER TIPS

If your base class implements the standard IDisposable pattern, all you need to do is add the Dispose(bool disposing) override to each derived class that itself owns IDisposable or unmanaged resources:

protected override void Dispose(bool disposing)
{
    try
    {
        if (disposing)
        {
            // Release managed resources
        }
        // Release unmanaged resources
    }
    finally
    {
        base.Dispose(disposing);
    }
}

You shouldn't implement finalizers in any of the derived classes.

And, of course, any classes in the hierarchy that don't have their own IDisposable resources don't need this override.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top