The try and catch blocks

   


The try and catch blocks

The exception message provided by the default exception handler, as demonstrated in the sample output from Listing 19.1, is useful for a programmer analyzing his or her source code. However, most end users would be baffled by a program that abruptly terminates and writes out, for them, a cryptic message.

To avoid this kind of behavior and let the program take corrective actions instead without terminating the program, we can enclose the code we want to monitor for special conditions inside a try block. After the try block, we can insert one or more catch blocks that specify the different exception object types we want to handle. I have used this approach on Listing 19.1 to form Listing 19.2, where the division by zero block in line 32 has been enclosed inside a try block that is immediately followed by a matching catch block.

Listing 19.2 SimpleTryCatch.cs
01: using System; 02: 03: class MyClass 04: { 05:     public static void Main() 06:     { 07:         Console.WriteLine("Entering MyClass.Main"); 08:         YourClass yourObject = new YourClass(); 09:         yourObject.Method1(); 10:         Console.WriteLine("Leaving MyClass.Main"); 11:     } 12: } 13: 14: class YourClass 15: { 16:     public void Method1() 17:     { 18:         Console.WriteLine("Entering YourClass.Method1"); 19:         Method2(); 20:         Console.WriteLine("Leaving YourClass.Method1"); 21:     } 22: 23:     public void Method2() 24:     { 25:         Console.WriteLine("Entering YourClass.Method2"); 26:         int myInt = 0; 27:         int yourInt; 28:         try 29:         { 30:             Console.WriteLine("Entering try block"); 31:              //Dividing by zero 32:             yourInt = 10 / myInt; 33:             Console.WriteLine("Leaving try block"); 34:         } 35:         catch(DivideByZeroException exObj) 36:         { 37:             Console.WriteLine("Entering catch block"); 38:             Console.WriteLine("Exception: " + exObj.Message); 39:             Console.WriteLine("Unable to automatically assign value to yourInt"); 40:             Console.Write("Please manually enter number to be assigned yourInt: "); 41:             yourInt = Convert.ToInt32(Console.ReadLine()); 42:             Console.WriteLine("Leaving catch block"); 43:         } 44:         Console.WriteLine("Leaving YourClass.Method2"); 45:     } 46: } Entering MyClass.Main Entering YourClass.Method1 Entering YourClass.Method2 Entering try block Entering catch block Exception: Attempted to divide by zero. Unable to automatically assign value to yourInt Please manually enter number to be assigned yourInt: 34<enter> Leaving catch block Leaving YourClass.Method2 Leaving YourClass.Method1 Leaving MyClass.Main 

After an exception is thrown inside a try block, the execution flow is immediately transferred outside the try block into a following catch block that matches the thrown exception; the flow is never returned to the try block. For this reason, line 33 is never executed.

The purpose of the catch block is to resolve the special condition and then let the program continue in its usual manner. In our case, the catch block notifies the user of the problem in a user-friendly manner and lets him or her assign a value to yourInt manually because the program is unable to perform this task automatically.

As part of transferring the flow of execution to the matching catch block, a reference to an appropriate exception object is automatically assigned to exObj of line 35. This exception object contains functions that let you access the information (about the special condition that caused the creation of this object) encapsulated by this object. One of these functions is a property called Message, which provides a short description of the exception. We utilize this functionality in line 38 to inform the user about the problem at hand. In our case, the Message property returns the following string:

 Attempted to divide by zero 

as shown in the sample output.

You can find further information about Message and the other useful functions exposed by the System.Exception class and its subclasses in the .NET Framework Documentation.

Observe how the try-catch unit allows us to separate the special case code in the catch block from the normal case code of the try block that provides the expected functionality of the program. As a result, we effectively prevent the special case code from polluting the normal case code.

The matching catch block prevents the program from being abruptly terminated. Instead, the program flow continues to the statement following the catch block, which, in this case, is line 44. From here, the program continues as if no exception was ever thrown.

If we exchanged DivideByZeroException in line 35 of Listing 19.2 with, say, ArgumentNullException, the catch blocks would no longer have matched the thrown DivideByZeroException exception. As a result, the execution object would have moved up through the chain of method calls similar to that of Listing 19.1. If, on the other hand, we substituted the DivideByZeroException with the ancestor class System.Exception, the catch block would match any possible exception object thrown.

To catch any possible exception object, you could also insert a generic catch block (see Figure 19.1), which doesn't carry any pair of parentheses after the catch keyword enclosing the parameter.

Figure 19.1. The generic catch block.
graphics/19fig01.gif

However this approach does not give you access to the execution object and its useful functions.


   


C# Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 286
Authors: Stephen Prata

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