Abusing using statements


I’ve always thought that the using statement was one of the most useful features included in C#.  It’s easy to use:

public string GetFileTextForParsing(string path)
{
    string contents = null;

    using(StreamReader reader = File.OpenText(path))
    {
        contents = reader.ReadToEnd();
    }

    return contents;
}

The using statement allows me to create scope for a variable, ensuring any expensive resources are cleaned up at the end of the using block.  To be able to take advantage of the using statement, the variable created inside the “using ()” must implement the IDisposable interface.

At a recent presentation of the new ASP.NET MVC framework, I saw a rather strange use of the using statement that bordered on abuse.  It’s from the MVC Toolkit, which Rob Conery introduced a while back.  The UI helpers are very nice, but it introduced a rather interesting way of creating HTML form elements:

<% using (Html.Form<HomeController>(action=>action.Index())) { %>

<input type="text" id="search" />

<input type="button" value="Submit" />

<% } %>

When this code executes, it creates the proper HTML form tags.  The using statement is used because it can create both the beginning form tag at the beginning of the using block and the end form tag at the end of the using block.

I’m seen some pretty creative uses of the using statement (that’s actually my very first blog post, ever), but this one rubbed me the wrong way.  The traditional usage of the using statement is simply to provide an easy syntax to properly use IDisposable instances.  IDisposable has a rather specialized description in MSDN documentation:

Defines a method to release allocated unmanaged resources.

I don’t think the Form method above has unmanaged resources.  That isn’t to say that IDisposable should only be used to for objects with unmanaged resources, like database connections, file handles, etc, as the using statement makes it such a palatable feature.  Some common uses for IDisposable include:

  • Cleaning up resources (database connections)
  • Creating scope for an operation (RhinoMocks record and playback)
  • Creating a context for a certain state (security impersonation)

The problem with the proliferation of IDisposable is we’ve reached the point where the IDisposable interface has no meaning in and of itself.  It’s morphed into a convenient way to allow use of the using statement.  What’s made the using statement so popular is that it provides a convenient syntax to encapsulate

  1. Code to be executed at the beginning of a block (the constructor)
  2. Code to be executed at the end of a block (the Dispose method)

Figuring out if I can use the using statement with a given object or method call is a deductive process.  Unless the class or method is named in a manner that makes it obvious that I’m creating a scope block, like “CreateContext”, I have to rely on documentation, examples, or Reflector to know that I’m supposed to use IDisposable.

Additionally, there’s nothing stopping me from not using the using statement.  For example, in the ASP.NET example above, let’s try removing the using statement:

<% Html.Form<HomeController>(action=>action.Index()); %>

<input type="text" id="search" />

<input type="button" value="Submit" />

This results in the end form tag never getting generated.  This means that we’re absolutely relying on developers to either call the Dispose method or use the using statement.

###

A new interface?

It used to be easy to know which objects needed to be disposed of properly, as these objects used unmanaged resources or had the explicit purpose of creating a context.  Since the using statement is such a convenient language feature, the IDisposable interface is used in a much wider variety of scenarios.  All these extra scenarios have made the existence of the IDisposable interface little more than a mechanism to take advantage of the IDisposable interface.

The name doesn’t make much sense anymore, as a fraction of the implementations of IDisposable are actually to clean up unmanaged resources.  A more appropriate name for IDisposable might be “IScopeable” or “IContext”, anything that better describes what its use has become.

Changing the name isn’t feasible, but what I’d really like to see are compiler warnings or Resharper code analysis warnings telling me when I’m using an IDisposable instance without calling the Dispose method or including it with the using statement.  It’s just too much work to check every single type I run into to see if it implements IDisposable.

So as fun as the using statement might be, I’d like to see it either more obvious to discover that I need to use the using statement, or a little more restraint on slapping IDisposable on anything with two legs.

Making the permanent move