25Feb/091
Making the ‘using’ statement, more usable
I've felt the pain of having the using statement not being able to return a value before, and just chalked it up to a limitation of the language.
I never considered trying to find a better way, and usually ended up with something like:
void DoSomething()
{
XmlDocument xml = new XmlDocument();
using(var reader = new StreamReader(@"c:\somexmlfile.xml"))
{
xml.Load(reader);
}
// do something useful with xml
}
or
void DoSomething2()
{
XmlDocument xml = new XmlDocument();
using( var reader = new StreamReader( @"c:\somexmlfile.xml" ) )
{
xml.Load( reader );
// do something useful with xml
}
}
Neither of which particularly suited me. Because
- First example: Declaring the variable outside the scope of the block feels weird
- Second example: Performing whatever operation inside the using block, means the file (or other resource) doesn't get released until the operation has completed.
After Shawn mentioned something about this at his Indy Alt.Net Clojure talk, I started thinking about it a little bit, and then I had a real need for it (again), and decided to come up with something better. Turns out what I wanted was blatantly simple.
TResult UsingReturn(TDisposable toUse, Func func) where TDisposable : IDisposable { using (toUse) { return func(toUse); } }
Now the above example turns into:
void DoSomething3()
{
var xml = UsingReturn( new StreamReader( @"c:\cdf.xml" ), reader =>
{
var doc = new XmlDocument();
doc.Load( reader );
return doc;
});
}
I'm not sure where this thing should live (e.g. some static utility class, extension method on IDisposable), or even what it should be called. Any ideas?

April 1st, 2009 - 22:41
Jon, this is good stuff too. Regarding where it should live and what it should be called … here’s an idea. It will be controversial, and truth is, I’m not 100% sold on it myself. But it’s food for thought:
Some things are so fundamental and likely to be used so commonly that they are almost like extensions to the language itself. Using those things should be easy and they should read “fluently” (in the general sense, not in the specific sense of “method chaining”). Maybe you put this in a static class named with one letter, like “X” for “eXtensions”. This is sort of like how Prototype and now many JavaScript libraries use $.