Section 16.8. The finally Statement


16.8. The finally Statement

In some instances, throwing an exception and unwinding the stack can create a problem. For example, if you opened a file or otherwise committed a resource, you might need an opportunity to close the file or flush the buffer.

If there is some action you must take regardless of whether an exception is thrown, such as closing a file, you have two strategies to choose from. One approach is to enclose the dangerous action in a try block and then to perform the necessary action (close the file) in both the catch and TRy blocks. However, this is an ugly duplication of code, and it's error prone. C# provides a better alternative in the finally block.

You create a finally block with the keyword finally , and you enclose the block in braces. The code in the finally block is guaranteed to be executed regardless of whether an exception is thrown. The TestFunc( ) method in the next listing, Example 16-5, simulates opening a file as its first action. The method then undertakes some mathematical operations, and then the file is closed.

A finally block can be created with or without catch blocks, but a finally block requires a try block to execute. It is an error to exit a finally block with break , continue , return , or goto .


It is possible that sometime between opening and closing the file, an exception will be thrown. If this were to occur, it would be possible for the file to remain open . The developer knows that no matter what happens, at the end of this method, the file should be closed, so the file close function call is moved to a finally block, where it is executed regardless of whether an exception is thrown. Example 16-5 uses a finally block.

Example 16-5. Using a finally block
 using System; namespace UsingAFinallyBlock {    class Tester    {       public void Run(  )       {          try          {             Console.WriteLine( "Open file here" );             double a = 5;             double b = 0;             Console.WriteLine( "{0} / {1} = {2}",             a, b, DoDivide( a, b ) );             Console.WriteLine(             "This line may or may not print" );          }          // most derived exception type first          catch ( DivideByZeroException )          {             Console.WriteLine(             "DivideByZeroException caught!" );          }          catch          {             Console.WriteLine( "Unknown exception caught" );          }          finally          {             Console.WriteLine( "Close file here." );          }       }       // do the division if legal       public double DoDivide( double a, double b )       {          if ( b == 0 )             throw new DivideByZeroException(  );          if ( a == 0 )             throw new ArithmeticException(  );          return a / b;       }       static void Main(  )       {          Console.WriteLine( "Enter Main..." );          Tester t = new Tester(  );          t.Run(  );          Console.WriteLine( "Exit Main..." );       }    } } 

The output looks like this:

 Enter Main...     Open file here     DivideByZeroException caught!     Close file here.     Exit Main... 

In Example 16-5, one of the catch blocks from Example 16-4 has been eliminated to save space and a finally block has been added. Whether or not an exception is thrown, the finally block is executed; thus, in both examples, the following message is output:

 Close file here. 

Of course, in a real application, you would actually open the file in the try block, and you'd actually close the file in the finally block. The details of file manipulation have been eliminated to keep the example simple.



Learning C# 2005
Learning C# 2005: Get Started with C# 2.0 and .NET Programming (2nd Edition)
ISBN: 0596102097
EAN: 2147483647
Year: 2004
Pages: 250

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net