Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# 2008 Step by Step.pdf
Скачиваний:
27
Добавлен:
25.03.2016
Размер:
14 Мб
Скачать
☆

104

Part I Introducing Microsoft Visual C# and Microsoft Visual Studio 2008

Trying Code and Catching Exceptions

C# makes it easy to separate the error handling code from the code that implements the main flow of the program by using exceptions and exception handlers. To write exceptionaware programs, you need to do two things:

1.Write your code inside a try block (try is a C# keyword). When the code runs, it attempts to execute all the statements inside the try block, and if none of the state-

ments generates an exception, they all run, one after the other, to completion. However, if an error condition occurs, execution jumps out of the try block and into another piece of code designed to catch and handle the exception—a catch handler.

2.Write one or more catch handlers (catch is another C# keyword) immediately after the try block to handle any possible error conditions. A catch handler is intended to catch and handle a specific type of exception, and you can have multiple catch handlers after a try block, each one designed to trap and process a specific exception so that you can provide different handlers for the different errors that could arise in the try block. If any one of the statements inside the try block causes an error, the runtime generates and throws an exception. The runtime then examines the catch handlers after the try block and transfers control directly to the first matching handler.

Here’s an example of code in a try block that attempts to convert strings that a user has typed in some text boxes on a form to integer values, call a method to calculate a value, and write the result to another text box. Converting a string to an integer requires that the string

contain a valid representation and not some arbitrary sequence of characters. If the string contains invalid characters, the int.Parse method throws a FormatException, and execution

transfers to the corresponding catch handler. When the catch handler finishes, the program continues with the first statement after the handler:

try

{

int leftHandSide = int.Parse(lhsOperand.Text); int rightHandSide = int.Parse(rhsOperand.Text);

int answer = doCalculation(leftHandSide, rightHandSide); result.Text = answer.ToString();

}

catch (FormatException fEx)

{

// Handle the exception

...

}

Chapter 6 Managing Errors and Exceptions

105

Handling an Exception

A catch handler uses syntax similar to that used by a method parameter to specify the exception to be caught. In the preceding example, when a FormatException is thrown,

the fEx variable is populated with an object containing the details of the exception. The FormatException type has a number of properties that you can examine to determine the

exact cause of the exception. Many of these properties are common to all exceptions. For example, the Message property contains a text description of the error that caused the ex-

ception. You can use this information when handling the exception, perhaps recording the details to a log file or displaying a meaningful message to the user and asking the user to try again.

Unhandled Exceptions

What happens if a try block throws an exception and there is no corresponding catch handler? In the previous example, it is possible that the lhsOperand text box contains the

string representation of a valid integer, but the integer that it represents is outside the range of valid integers supported by C# (for example, “2147483648”). In this case, the int.Parse statement will throw an OverflowException, which will not be caught by the FormatException catch handler. If this occurs, if the try block is part of a method, the method immediately

exits and execution returns to the calling method. If the calling method uses a try block, the

runtime attempts to locate a matching catch handler after the try block in the calling method and execute it. If the calling method does not use a try block, or there is no matching catch

handler, the calling method immediately exits and execution returns to its caller, where the process is repeated. If a matching catch handler is eventually found, the handler runs and execution continues with the first statement after the catch handler in the catching method.

Important Notice that after catching an exception, execution continues in the method

containing the catch block that caught the exception. If the exception occurred in a method other than the one containing the catch handler, control does not return to the method that

caused the exception.

If, after cascading back through the list of calling methods, the runtime is unable to find a matching catch handler, the program terminates with an unhandled exception. If you are

running the application in Microsoft Visual Studio 2008 in debug mode (you selected Start Debugging on the Debug menu to run the application), the following information dialog box

appears and the application drops into the debugger, allowing you to determine the cause of the exception:

106

Part I Introducing Microsoft Visual C# and Microsoft Visual Studio 2008

 

 

 

 

Using Multiple catch Handlers

The previous discussion highlights how different errors throw different kinds of exceptions to represent different kinds of failures. To cope with these situations, you can supply multiple catch handlers, one after the other, like this:

try

{

int leftHandSide = int.Parse(lhsOperand.Text); int rightHandSide = int.Parse(rhsOperand.Text);

int answer = doCalculation(leftHandSide, rightHandSide); result.Text = answer.ToString();

}

catch (FormatException fEx)

{

//...

}

catch (OverflowException oEx)

{

//...

}

Catching Multiple Exceptions

The exception-catching mechanism provided by C# and the Microsoft .NET Framework is quite comprehensive. Many different exceptions are defined in the .NET Framework, and any

Chapter 6 Managing Errors and Exceptions

107

programs you write will be able to throw most of them! It is highly unlikely that you will want to write catch handlers for every possible exception that your code can throw. So how do you

ensure that your programs catch and handle all possible exceptions?

The answer to this question lies in the way the different exceptions are related to one

another. Exceptions are organized into families called inheritance hierarchies. (You will learn about inheritance in Chapter 12, “Working with Inheritance.”) FormatException and OverflowException both belong to a family called SystemException, as do a number of other

exceptions. Rather than catching each of these exceptions individually, you can create a handler that catches SystemException. SystemException is a member of a family simply called Exception, which is the great-granddaddy of all exceptions. If you catch Exception, the handler

traps every possible exception that can occur.

Note The Exception family includes a wide variety of exceptions, many of which are intended for use by various parts of the .NET Framework. Some of these are somewhat esoteric, but it is still useful to understand how to catch them.

The next example shows how to catch all possible system exceptions:

try

{

int leftHandSide = int.Parse(lhsOperand.Text); int rightHandSide = int.Parse(rhsOperand.Text);

int answer = doCalculation(leftHandSide, rightHandSide); result.Text = answer.ToString();

}

catch (Exception ex) // this is a general catch handler

{

//...

}

Tip If you want to catch Exception, you can actually omit its name from the catch handler because it is the default exception:

catch

{

// ...

}

However, this is not always recommended. The exception object passed in to the catch handler can contain useful information concerning the exception, which is not accessible when using this version of the catch construct.

There is one final question you should be asking at this point: What happens if the same exception matches multiple catch handlers at the end of a try block? If you catch

108 Part I Introducing Microsoft Visual C# and Microsoft Visual Studio 2008

FormatException and Exception in two different handlers, which one will run (or will both execute)?

When an exception occurs, the first handler found by the runtime that matches the excep-

tion is used, and the others are ignored. What this means is that if you place a handler for Exception before a handler for FormatException, the FormatException handler will never run.

Therefore, you should place more-specific catch handlers above a general catch handler after a try block. If none of the specific catch handlers matches the exception, the general catch

handler will.

In the following exercise, you will write a try block and catch an exception.

Write a statement

1.Start Visual Studio 2008 if it is not already running.

2.Open the MathsOperators solution located in the \Microsoft Press\Visual CSharp Step By Step\Chapter 6\MathsOperators folder in your Documents folder.

This is a variation on the program that you first saw in Chapter 2, “Working with Variables, Operators, and Expressions.” It was used to demonstrate the different arithmetic operators.

3.On the Debug menu, click Start Without Debugging.

The form appears. You are now going to enter some text that is deliberately not valid in the left operand text box. This operation will demonstrate the lack of robustness in the current version of the program.

4.Type John in the left operand text box, and then click Calculate.

A dialog box reports an unhandled exception; the text you entered in the left operand text box caused the application to fail.

Note The Debug button does not appear if you are using Microsoft Visual C# 2008

Express Edition.

You might see a different version of this dialog box (shown later) depending on how

you have configured problem reporting in Control Panel. If you see this dialog box, simply click the Close the program link whenever the instructions in the following steps refer to the Close Program button, and click the Debug the program link whenever

Chapter 6 Managing Errors and Exceptions

109

the instructions refer to the Debug button. (If you are using Windows XP rather than Windows Vista, you will see a different dialog box with Debug, Send Error Report, and Don’t Send buttons. Click the Don’t Send button to close the program.)

5.If you are using Visual Studio 2008, click Debug. In the Visual Studio Just-In-Time Debugger dialog box, in the Possible Debuggers list box, select MathsOperators – Microsoft Visual Studio: Visual Studio 2008, and then click Yes:

6.If you are using Visual C# 2008 Express Edition, click Close Program. On the Debug menu, click Start Debugging. Type John in the left operand text box, and then click Calculate.

7.Whether you are using Visual Studio 2008 or Visual C# 2008 Express Edition, the Visual Studio 2008 debugger starts and highlights the line of code that caused the exception and displays some additional information about the exception:

110

Part I Introducing Microsoft Visual C# and Microsoft Visual Studio 2008

 

 

 

 

 

 

You can see that the exception was thrown by the call to int.Parse inside the calculateClick method. The problem is that this method is unable to parse the text

“John” into a valid number.

Note You can view the code that caused an exception only if you actually have the source code available on your computer.

8.On the Debug menu, click Stop Debugging.

9.Display the code for the file Window1.xaml.cs in the Code and Text Editor window, and locate the calculateClick method.

10.Add a try block (including braces) around the four statements inside this method, as shown in bold type here:

try

{

int leftHandSide = int.Parse(lhsOperand.Text); int rightHandSide = int.Parse(rhsOperand.Text);

int answer = doCalculation(leftHandSide, rightHandSide); result.Text = answer.ToString();

}

11. Add a catch block immediately after the closing brace for this new try block, as follows:

catch (FormatException fEx)

{

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]