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