Kevin said:
The using statement block ensures that the IDisposable class instantiated in
the beginning of the statement is disposed as soon as the block is exited.
It is the equivalent of using try/catch/finally, and calling Dispose on the
IDisposable class instantiated in the try block.
A very minor point, admittedly, but the above is not strictly correct.
In particular, the object being disposed is not instantiated or
otherwise initialized within the try block. The only thing that winds
up in the try block is the code that's in the using statement's embedded
statement (the code immediately following the using statement). The
using statement is equivalent to initializing the variable outside the
try/finally block.
So:
using (SomeType obj = ...)
{
// some code here
}
Is equivalent to:
{
SomeType obj = ...;
IDisposable objHidden = (IDisposable)obj;
try
{
// some code here
}
finally
{
if (objHidden != null)
{
objHidden.Dispose();
}
}
}
The spec describes it slightly differently, but IMHO the above makes it
a little more clear (at least if I have understood the spec correctly
). Specifically, according to the spec the variable used for the actual
dispose at the end is initialized by the expression in the using
statement ("..." above), is read-only and inaccessible by the program
itself (so no matter what you do to the visible variable in the embedded
statement of the using statement, the original object is the one that
gets disposed).
Some other possibly interesting behaviors implicit in the "using"
statement beyond those illustrated above:
Obviously, SomeType must implement IDisposable, otherwise a compiler
error occurs.
Also, if SomeType isn't a nullable type, then of course the check for
null isn't done in the "finally" block.
Hope that helps more than confuses the issue.
Pete