The finally Clause


A block of code may be defined such that it is executed when a try-catch is left - no matter how the block is exited. A block of code that is executed when the try-catch block is exited is specified by including a finally clause. The syntax for including a finally clause is shown below.

try
 {
  ...
 }
catch(ExceptionType1 exceptionObject1)
{
 ...
}
catch(ExceptionType2 exceptionObject2)
{
 ...
}
...
...
finally
 {
  ...
 }

A program that tests the various options for exiting a try-catch with a finally clause is shown below.

// Exception11 - finally

using System;

enum TestType
{
    NoError,      // Test Normal Exit from try
    Exception,    // Test throwing an exception
    Return        // Test Returning from handler
}

class Program
{
    static void TestFinally(TestType tt)
    {
        try
        {
            switch (tt)
            {
                case TestType.NoError:
                    break;

                case TestType.Exception:
                    throw new DivideByZeroException();

                case TestType.Return:
                    throw new IndexOutOfRangeException();
            }
        }
        catch (DivideByZeroException)
        {
            Console.WriteLine("DivideByZeroException encountered");
        }
        catch (IndexOutOfRangeException)
        {
            Console.WriteLine("DivideByZeroException encountered - returning");
            return;
        }
        finally
        {
            Console.WriteLine("In Finally - Leaving Try");
        }
    }

    static void Main()
    {
        TestFinally(TestType.Exception);
        TestFinally(TestType.Return);
        TestFinally(TestType.NoError);
    }
}

The output from the program is shown below.

DivideByZeroException encountered
In Finally - Leaving Try
IndexOutOfRangeException encountered - returning
In Finally - Leaving Try
In Finally - Leaving Try

An enumeration is used to test three cases. The first case is TestType.Exception. This is an example of exiting a try-catch block by throwing an exception. The DivideByZeroException is caught and a message is printed. When the handler completes, control is transferred to the finally clause and it too executes its code (which prints another message). The next case is TestType.Return. The difference between this case and the previous case is that the handler returns after processing the exception IndexOutOfRangeException. Despite returning, control is transferred to the finally clause then the return is effected. The third case is TestType.NoError. This case is when no exception is thrown inside the try-catch block. The finally clause is also executed in this case.