Exception Handling in C# - Using Statements
(Page 6 of 8 )
In C#, the nearest you can get to the "ideal" version is this:
private
static char[] ReadSource(string filename)
{
FileInfo file = new FileInfo(filename);
int length = (int)file.Length;
char[] source = new char[length];
using (TextReader reader = file.OpenText())
{
reader.Read(source, 0, length);
}
return source;
}
This is pretty close. And as I'll explain shortly it has a number of features that improve on the "ideal" version. But first let's look under the lid to see how it actually works.
Using Statement Translation
The C# ECMA specification states that a using statement:
using
(type variable = initialization)
embeddedStatement
is exactly equivalent to:
{
type variable = initialization;
try
{
embeddedStatement
}
finally
{
if (variable != null)
{
((IDisposable)variable).Dispose();
}
}
}
This relies on the IDisposable interface from the System namespace:
namespace System
{
public interface IDisposable
{
void Dispose();
}
}
Note that the cast inside the finally block implies that variable must be of a type that supports the IDisposable interface (either via inheritance or conversion operator). If it doesn't you'll get a compile time error.
Using TextReader Translation
Not surprisingly, TextReader supports the Disposable interface and implements Dispose to call Close. This means that this:
using
(TextReader reader = file.OpenText())
{
reader.Read(source, 0, length);
}
is translated, under the hood, into this:
{
TextReader reader = file.OpenText();
try
{
reader.Read(source, 0, length);
}
finally
{
if (reader != null)
{
((IDisposable)reader).Dispose();
}
}
}
Apart from the cast to IDisposable this is identical to the best general Java solution. The cast is required because this is a general solution.
Next: Do it Yourself? >>
More C# Articles
More By Jon Jagger