According to MSDN and this accepted answer,
using (T resource = expression)
embedded-statement
is translated by the compiler as the following code:
{
T resource = expression;//Shouldn't this statement be moved inside the try block?
try
{
embedded-statement
}
finally
{
if (resource != null)
((IDisposable)resource).Dispose();
}
}
My question is: Why is there an extra {} around the try block? Shouldn't the first statement be moved inside the try block?
MSDN explains:
The code example earlier expands to the following code at compile time (note the extra curly braces to create the limited scope for the object):
But according to another MSDN page,
By using a finally block, you can clean up any resources that are allocated in a try block
Updated: If variable visibility is the reason, then how about we declare the variable first and assign it null, then initialize it inside the try block? Is this better than the original code?
{
T resource = null;//Now it is visible in the try block
try
{
resource =expression;// in case an exception is thrown here
embedded-statement
}
finally
{
if (resource != null)
((IDisposable)resource).Dispose();
}
}
Why is there an extra
{}around the try block?
Because the using statement is not equivalent to:
T resource = expression;
try
{
embedded-statement
}
finally
{
if (resource != null)
((IDisposable)resource).Dispose();
}
// resource is still in scope here!
resource is still in scope after the above code, but it should not be in scope after the using statement.
Imagine if resource is also the name of a field, and you have put Console.WriteLine(resource); after the using statement. Normally, it would have printed the field, but if the using statement were replaced by the code above, then you would have printed the resource you just allocated instead!
Therefore, to ensure that the semantics remain the same, the extra {} is needed.
Shouldn't the first statement be moved inside the try block?
No. The using statement is designed to throw an exception if the initialisation of the resource fails.
By using a finally block, you can clean up any resources that are allocated in a try block
Yes, but that does not mean you have to put every resource in a try block, nor does that mean putting resources in a try block is the only way to clean them up.
If the initialisation of resource throws an exception, the resource will not be initialised, so there is no resource to be disposed of anyway - the finally block does not need to run in this case, so it is totally fine to put that line outside of the try.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With