Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is abusing IDisposable to benefit from "using" statements considered harmful? [closed]

The purpose of the interface IDisposable is to release unmanaged resources in an orderly fashion. It goes hand in hand with the using keyword that defines a scope after the end of which the resource in question is disposed of.

Because this meachnism is so neat, I've been repeatedly tempted to have classes implement IDisposable to be able to abuse this mechanism in ways it's not intended for. For example, one could implement classes to handle nested contexts like this:

class Context : IDisposable
{
    // Put a new context onto the stack
    public static void PushContext() { ... }

    // Remove the topmost context from the stack
    private static void PopContext() { ... }

    // Retrieve the topmost context
    public static Context CurrentContext { get { ... } }

    // Disposing of a context pops it from the stack
    public void Dispose()
    {
        PopContext();
    }
}

Usage in calling code might look like this:

using (Context.PushContext())
{
   DoContextualStuff(Context.CurrentContext);
} // <-- the context is popped upon leaving the block

(Please note that this is just an example and not to the topic of this question.)

The fact that Dispose() is called upon leaving the scope of the using statement can also be exploited to implement all sorts of things that depend on scope, e.g. timers. This could also be handled by using a try ... finally construct, but in that case the programmer would have to manually call some method (e.g. Context.Pop), which the using construct could do for thon.

This usage of IDisposable does not coincide with its intended purpose as stated in the documentation, yet the temptation persists.

Are there concrete reasons to illustrate that this is a bad idea and dispell my fantasies forever, for example complications with garbage collection, exception handling, etc. Or should I go ahead and indulge myself by abusing this language concept in this way?

like image 526
waldrumpus Avatar asked Apr 14 '15 13:04

waldrumpus


2 Answers

So in asp.net MVC views, we see the following construct:

using(Html.BeginForm())
{
    //some form elements
}

An abuse? Microsoft says no (indirectly).

If you have a construct that requires something to happen once you're done with it, IDisposable can often work out quite nicely. I've done this more than once.

like image 65
spender Avatar answered Nov 19 '22 17:11

spender


"Is it an abuse of the IDisposable interface to use it this way"? Probably.

Does using using as a purely "scoping" construct make for more obvious intent and better readability of code? Certainly.

The latter trumps the former for me, so I say use it.

like image 3
Ian Kemp Avatar answered Nov 19 '22 16:11

Ian Kemp