Search code examples
c#destructordisposeidisposable

Should I add a destructor/finalizer to my class that contains a Dataset?


I've read through this post about disposing of datasets and I still have a question about the destructor. I know that post basically says that you don't need to dispose of Datasets, Datatables, and Dataviews, but my dataset is MASSIVE, so I want to release that memory ASAP. So, my question, should I include a destructor even though the dataset will be disposed when my objects' dispose method is called? Also, explain to me again why the "bool disposing" is needed.

        public DEditUtil(DataSet dsTxData)
    {
        this.dsTxData = dsTxData;
    }

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

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
                dsTxData.Dispose();

            disposed = true;
        }
    }

    ~DEditUtil()
    {
        Dispose(false);
    }

Solution

  • Yes, in general you should implement the full IDisposable pattern whenever either of the following is true:

    1. You have unmanaged resources being allocated by your class, or
    2. You have managed resources that implement IDisposable (which implies that they, in turn, have unmanaged resources)

    The presence of the finalizer (the general CLR term for what C++/C# call a "destructor") is to handle cases where your Dispose method is not called for some reason. The boolean value being passed in to your protected Dispose() method indicated if you are being called from within the public Dispose, or from within your finalizer.

    If your public Dispose method is being called, that call stack is deterministic: your dispose method is being called directly, so you can safely call methods (including Dispose) on your child objects.

    If you are inside of the finalizer, then you have no idea what's going on with other objects that are also being garbage-collected. In general, it may not be safe to call methods on managed objects your control from within your finalizer.

    So, the boolean value basically says: "if true, dispose everything; if false, only dispose my unmanaged resources and let everyone else deal with theirs."