Consider the following code:
using System;
public class Program
{
public static void Main(string[] args)
{
using (var myDisposable = new MyDisposable())
{
myDisposable.DoThing();
}
// not allowed, myDisposable is out of scope
//myDisposable.DoThing();
}
}
public class MyDisposable : IDisposable
{
public void DoThing()
{
// method intentionally left blank
}
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
Assuming the standard description of the using statement, this is how lines 7-12 above are expanded by the compiler:
var myDisposable = new MyDisposable();
try
{
myDisposable.DoThing();
}
finally
{
if (myDisposable != null)
{
((IDisposable)myDisposable).Dispose();
}
}
// not allowed, myDisposable is out of scope
//myDisposable.DoThing();
However, the comment at line 13 is no longer correct; the variable myDisposable is now available in the whole method following its declaration.
Variable Scope
Assuming a variable is declared within the using statement, the compiler will scope that variable, by adding a set of braces around its usage. Here's the full method as it is compiled - note the braces at lines 3 and 16:
public static void Main(string[] args)
{
{
var myDisposable = new MyDisposable();
try
{
myDisposable.DoThing();
}
finally
{
if (myDisposable != null)
{
((IDisposable)myDisposable).Dispose();
}
}
}
// not allowed, myDisposable is out of scope
//myDisposable.DoThing();
}
Of course, it is possible to live more dangerously by applying the using statement on a variable declared outside scope of the using statement:
public static void Main(string[] args)
{
var myDisposable = new MyDisposable();
using (myDisposable)
{
myDisposable.DoThing();
}
// careful, myDisposable has been disposed
myDisposable.DoThing();
}
... if you do that, good luck.
No comments:
Post a Comment