Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will this be a valid base class for IDisposable

IDisposable pattern is expensive to implement. I've counted 17 lines of code before even starting to actually dispose resources.

Eric Lippert recently wrote a blog post bringing up an interesting point: any time a finalizer runs, it is a bug. I think it make perfect sense. If the IDisposable pattern is always followed, Finalizer should always be suppressed. It will never have a chance to run. If we accept that finalizer run is a bug, then does it make sense to have a guideline to force developers to derive from the following abstract class and forbid directly implementing the IDisposable interface.

public abstract class AbstractDisaposableBase: IDisposable
{
    ~AbstractDisaposableBase()
    {
        ReportObjectLeak();
        Dispose(false); 
    }

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

    protected abstract void Dispose(bool disposing);

    [Conditional("DEBUG")]
    private void ReportObjectLeak()
    {
        //Debug.Assert(false, "leaked instance");
        //throw new Exception("leaked instance");
    }
}

The benefits are clear:

  1. Implementing dispose becomes easy and error free like below:


class MyClass1 : DisablableBase
{
    protected override void Dispose(bool disposing)
    {
        //dispose both managed and unmamaged resources as though disposing==true
    }
}
  1. Not disposed object got reported

  2. Disposable pattern is always followed

But, is there any problem with such a guideline?

One possible problem is that all disposable object will have a finalizer defined. But since the finalizer is always suppressed, there should not be any performance penalties.

What are your thoughts?

like image 651
Xiaoguo Ge Avatar asked Sep 03 '15 10:09

Xiaoguo Ge


People also ask

What is a IDisposable class?

IDisposable is an interface that contains a single method, Dispose(), for releasing unmanaged resources, like files, streams, database connections and so on.

How can we use IDisposable class?

For implementing the IDisposable design pattern, the class which deals with unmanaged objects directly or indirectly should implement the IDisposable interface. And implement the method Dispose declared inside of the IDisposable interface. We do not directly deal with unmanaged objects.

Why do we implement IDisposable interface in C#?

IDisposable is defined in the System namespace. It provides a mechanism for releasing unmanaged resources. When your application or class library encapsulates unmanaged resources such as files, fonts, streams, database connections, etc, they should implement the IDisposable interface or the IAsyncDisposable interface.

Why do we need IDisposable?

You never know when the garbage collector will collect your object. You don't even know if it even will (unlike using delete in C++, which is deterministic). So IDisposable is there for deterministically releasing unneeded references (and releasing unmanaged resources).


1 Answers

does it make sense to have a guideline to force developers to derive from the following abstract class

No, solely for the reason that C# doesn't have multiple inheritance. Interfaces describe behavior, inheritance dictates "is-a". You'll thoroughly limit the object-oriented design of your classes if you enforce this rule.

For example you can't introduce base classes for business objects that are not disposable, where a derived class would be.

like image 162
CodeCaster Avatar answered Oct 01 '22 22:10

CodeCaster