// 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. // 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. public static void ExampleCar54() { Console.WriteLine("***** Handling Multiple Exceptions *****\n"); Car5 myCar = new Car5("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); } }
// Rethrowing Exceptions // --------------------------------------------------------------------------------------------------------------- // Be aware that if the Method is the Main() method, the ultimate receiver of Exception is the CLR because it // is the Main() method rethrowing the exception.Because of this, your end user is presented with a system // supplied error dialog box.Typically, you would only rethrow a partial handled exception to a caller // that has the ability to handle the incoming exception more gracefully. // Notice as well that you are not explicitly rethrowing the Exception object but rather making // use of the throw keyword with no argument. You’re not creating a new exception object; you’re just // rethrowing the original exception object (with all its original information). Doing so preserves // the context of the original target. public static void ExampleCar53() { Console.WriteLine("***** Custom Exception Example53 *****"); Console.WriteLine("=> Creating a car and stepping on it!"); Car5 myCar = new Car5("Zippy", 90); myCar.CrankTunes(true); try { // trip exception myCar.Accelerate(-10); } catch (Exception ex) { throw; } // The error has been handled, processing continues with the next statement. Console.WriteLine("\n----------- Out of exception logic ----------- "); // separator Console.WriteLine("".PadLeft(40, '=')); }
// Exception Filters // --------------------------------------------------------------------------------------------------------------- // C# 6 introduced a new clause that can be placed on a catch scope, via the when keyword. When you add // this clause, you have the ability to ensure that the statements within a catch block are executed only if some // condition in your code holds true. This expression must evaluate to a Boolean (true or false) and can be // obtained by using a simple code statement in the when definition itself or by calling an additional method in // your code.In a nutshell, this approach allows you to add “filters” to your exception logic. // First, assume you have added a few custom properties to your CarIsDeadException. public static void ExampleCar55() { Console.WriteLine("***** Exception Filtering with When Clause Test55 *****"); Console.WriteLine("=> Creating a car and stepping on it!"); Car5 myCar = new Car5("Zippy", 90); myCar.CrankTunes(true); try { // trip exception myCar.Accelerate(-10); } catch (CarIsDeadException ex) when(ex.ErrorTimeStamp.DayOfWeek != DayOfWeek.Friday) { Console.WriteLine($"-------------- CarIsDeadException, when day is not Friday --------------"); Console.WriteLine($"ex.Message : {ex.Message}"); Console.WriteLine($"ex.ErrorTimeStamp : {ex.ErrorTimeStamp}"); Console.WriteLine($"ex.CauseOfError : {ex.CauseOfError}"); } catch (ArgumentOutOfRangeException ex) { Console.WriteLine($"-------------- ArgumentOutOfRangeException --------------"); Console.WriteLine($"ex.Message : {ex.Message}"); } // This will catch any other exception // beyond CarIsDeadException or // ArgumentOutOfRangeException. catch (Exception e) { Console.WriteLine($"-------------- Exception --------------"); Console.WriteLine(e.Message); } // The error has been handled, processing continues with the next statement. Console.WriteLine("\n----------- Out of exception logic ----------- "); // separator Console.WriteLine("".PadLeft(40, '=')); }