CHAPTER 7 UNDERSTANDING STRUCTURED EXCEPTION HANDLING
Given that there is no “next caller” after Main() to catch the exception, we would be again presented
with an error dialog box. Much like the act of rethrowing an exception, recording inner exceptions is
usually only useful when the caller has the ability to gracefully catch the exception in the first place. If
this is the case, the caller’s catch logic can make use of the InnerException property to extract the details
of the inner exception object.
The finally Block
A try/catch scope may also define an optional finally block. The purpose of a finally block is to ensure
that a set of code statements will always execute, exception (of any type) or not. To illustrate, assume
you want to always power down the car’s radio before exiting Main(), regardless of any handled
exception:
static void Main(string[] args)
{
Console.WriteLine("***** Handling Multiple Exceptions *****\n");
Car myCar = new Car("Rusty", 90);
myCar.CrankTunes(true);
}
try
{
// Speed up car logic.
}
catch(CarIsDeadException e)
{
// Process CarIsDeadException.
}
catch(ArgumentOutOfRangeException e)
{
// Process ArgumentOutOfRangeException.
}
catch(Exception e)
{
// Process any other Exception.
}
finally
{
// This will always occur. Exception or not.
myCar.CrankTunes(false);
}
Console.ReadLine();
If you did not include a finally block, the radio would not be turned off if an exception is
encountered (which might or might not be problematic). In a more real-world scenario, when you need
to dispose of objects, close a file, or detach from a database (or whatever), a finally block ensures a
location for proper cleanup.
276