| Home | Biography | Speaking | Articles | Books | Music |
using StatementThere are two things I’d like to see added to the using statement. You know, it’s the statement you use when you’re playing with an IDisposable-based object:
public sealed class Disposable : IDisposable
{
public void Go()
{
}
public void Dispose()
{
}
}
using(Disposable disposable = new Disposable())
{
disposable.Go();
}
Essentially, C# generates code that looks something like this:
public void Use()
{
Disposable disposable = new Disposable();
try
{
disposable.Go();
}
finally
{
if (disposable != null)
{
disposable.Dispose();
}
}
}
One thing I’d like to see added is the ability to add exception handlers:
using(Disposable disposable = new Disposable())
{
disposable.Go();
}
catch(NotSupportedException)
{
// do something here...
}
This would expand to this:
public void Use()
{
Disposable disposable = new Disposable();
try
{
disposable.Go();
}
catch(NotSupportedException)
{
// do something here...
}
finally
{
if (disposable != null)
{
disposable.Dispose();
}
}
}
I’ve run into a number of cases where the creation of the object or one of its method calls will throw an exception that I can either handle and/or want to log. But since using doesn’t have any concept of exception handlers, I have to revert to writing the handler code myself.
The other feature request is a bit of an oddity. Let’s say Disposable explicity implemented an interface called IThingee:
public interface IThingee
{
void Whack();
}
public sealed class Disposable : IDisposable, IThingee
{
public void Go()
{
}
public void Dispose()
{
}
void IThingee.Whack()
{
}
}
Now I’m stuck. I can’t write this code:
using(IThingee thingee = new Disposable())
{
thingee.Whack();
}
Because the compiler will complain to me:
Error 1 'UsingComplaints.IThingee': type used in a using statement must be implicitly convertible to 'System.IDisposable'
But I can’t write this either:
using(Disposable thingee = new Disposable())
{
thingee.Whack();
}
Since IThingee is explicity implemented, the compiler barks at me with this:
Error 1 'UsingComplaints.Disposable' does not contain a definition for 'Whack'
So I’m back to manually writing the try … finally handler myself. What would be nice is if I use using on an object that does not “appear” to implement IDisposable, add a type check to the code that’s generated in the finally handler:
finally
{
if (thingee != null && thingee is IDisposable)
{
(thingee as IDisposable).Dispose();
}
}
This may not be as “performant” … but I’d have to do this anyway. If C# is willing to generate some code for me, might as well let it generate some more, eh?
Don’t get me wrong - I like the using statement. Most of the time it does the job. But I’ve always felt that using was added in a somewhat rushed fashion during the pre-1.0 .NET days. The analysis behind the idea is sound, but real-world situations have popped up that I think require using to be extended a bit.
Published: 05.30.2007 06:38:14 AM CST