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 (<object instantiated>)” 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.

Related Articles:

    Post Footer automatically generated by Add Post Footer Plugin for wordpress.

    About Jimmy Bogard

    I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
    This entry was posted in ASP.NET, C#, MVC. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
    • http://blog.wekeroad.com Rob Conery

      >>>The problem with the proliferation of IDisposable is we’ve reached the point where the IDisposable interface has no meaning in and of itself.< <<

      Hmmm – I think that’s a reach. IDisposable seems pretty clear to me. I would also argue that you’re being a bit literal here, are you not? I’m all for “doing things right” – but I don’t think you’ve supported your argument that I am “abusing” IDisposable.

      I do think, however, that you clearly illustrated why we did this – to give a compiler check that makes sure your form tag is closed.

      The second method you’ve pointed out here just generates a form tag – there is no disposable call on it. We’ve given a ton of options for you – personally I like using the “using” for the very reasons you’ve pointed out :)

    • Anders

      Mark Miller has example of marking classes that implements IDisposable without calling Dispose

      See http://www.doitwith.net/2007/04/20/HighlightingIDisposableLocalsThatDon'tCallDisposePartI.aspx

    • Sergio Pereira

      I agree with your sentiment. It’s definitely hard to discover when you need to “create a context” as yo well said.
      I think we might be looking for a more formal implementation of blocks in C#. Allow me to point you to two attempts at making those context blocks look natural. Still not there yet, but can be a direction:
      http://abombss.com/blog/2007/12/28/ms-mvc-gets-blocks-from-rails/
      http://www.sergiopereira.com/articles/xmlbuilder.html

    • http://darrell.mozingo.net Darrell Mozingo

      “It’s just too much work to check every single type I run into to see if it implements IDisposable.”

      Simply typing “ObjectInstance.Di” will have Intellisense tell you if it supports the IDisposable interface, no? It’s not that much work.

    • http://jimmybogard.lostechies.com Jimmy Bogard

      @Rob

      I think @Sergio put it better. What everyone is trying to do is create blocks, but it’s hard to discover if something needs to be called in a using block.

      Although you’ve given me the option of calling Dispose, it’s not easily known unless I happen to look at its inheritance hierarchy (all the way up) or I happen to notice a Dispose method.

      Sometimes I find types that explicitly implement IDisposable, in which case I never see the Dispose method. In those cases, I’m hosed. Hopefully there is a relevant method for me to call like “Close”.

      I just wish it was more visible that something implements IDisposable to me, through compiler warning or otherwise.

      @anders

      Thanks! I’m going to look into doing this in R#. That’s _really_ what I’d like, some warnings.

    • http://jimmybogard.lostechies.com Jimmy Bogard

      @Darrell

      That’s assuming the Dispose method is public. There’s no guarantee that it is. Here’s some numbers I get looking at all public IDisposable types in the System.* assemblies:

      Dispose method public: 395 types
      Dispose method non-public: 538 types

      Over half the time, it’s not public, so it’s not a safe assumption that Dispose will show up in Intellisense.

    • http://haacked.com/ Haacked

      Actually, the using statement and IDisposable was not intended sole for disposing of resources. It was intended to be a more general idea of “releasing” something. I wrote about this a while ago after discussing this with Eric Gunnerson when he was on the C# team.

      http://haacked.com/archive/2004/05/27/DifficultiesOfLanguageDesign.aspx

      Here’s the relevant section:

      I asked Eric Gunnerson whether they’ve considered adding a timeout syntax to the lock statement ala Ian Griffiths’ TimedLock structure. He in turn asked me, would creating this new syntax have any more clarity than using the TimedLock structure? Ummm… I guess not since we can already do this in a clean and concise manner. Right. So why add syntax. Not only that, the TimedLock demonstrates what the C# team had in mind with the using statement. It wasn’t intended just for cleanup, but for situations just like this.

      Naturally, if this were the case, why even have the lock statement, as the using statement makes it unnecessary. It turns out, the lock statement was introduced long before they introduced the using statement when creating the language. At that point it wouldn’t make sense to refactor the lock statement out of the language as it was likely used all over the place and would introduce a major breaking change (see the first reason why language design is hard). Wow, you mean real world issues such as timing will affect the purity of language design? Indeed, total purity is an illusion.