Free mag vol1 | Page 550

CHAPTER 13  UNDERSTANDING OBJECT LIFETIME // Assume you have imported // the System.IO namespace... static void DisposeFileStream() { FileStream fs = new FileStream("myFile.txt", FileMode.OpenOrCreate); } // Confusing, to say the least! // These method calls do the same thing! fs.Close(); fs.Dispose(); While it does feel more natural to “close” a file rather than “dispose” of one, this doubling up of cleanup methods can be confusing. For the few types that do provide an alias, just remember that if a type implements IDisposable, calling Dispose() is always a safe course of action. Reusing the C# using Keyword When you are handling a managed object that implements IDisposable, it is quite common to make use of structured exception-handling to ensure the type’s Dispose() method is called in the event of a runtime exception, like so: static void Main(string[] args) { Console.WriteLine("***** Fun with Dispose *****\n"); MyResourceWrapper rw = new MyResourceWrapper (); try { // Use the members of rw. } finally { // Always call Dispose(), error or not. rw.Dispose(); } } While this is a fine example of defensive programming, the truth of the matter is that few developers are thrilled by the prospects of wrapping each and every disposable type within a try/finally block just to ensure the Dispose() method is called. To achieve the same result in a much less obtrusive manner, C# supports a special bit of syntax that looks like this: static void Main(string[] args) { Console.WriteLine("***** Fun with Dispose *****\n"); // Dispose() is called automatically when the // using scope exits. using(MyResourceWrapper rw = new MyResourceWrapper()) { // Use rw object. } } 491