Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Daniel Solis - Illustrated C# 2010 - 2010.pdf
Скачиваний:
16
Добавлен:
11.06.2015
Размер:
11.23 Mб
Скачать

CHAPTER 11 EXCEPTIONS

Searching Further

If the exception was raised in a section of code that was not guarded by a try statement or if the try statement does not have a matching exception handler, the system will have to look further for a matching handler. It will do this by searching down the call stack, in sequence, to see whether there is an enclosing try block with a matching handler.

Figure 11-7 illustrates the search process. On the left of the figure is the calling structure of the code, and on the right is the call stack. The figure shows that Method2 is called from inside the try block of Method1. If an exception occurs inside the try block in Method2, the system does the following:

First, it checks to see whether Method2 has exception handlers that can handle the exception.

If so, Method2 handles it, and program execution continues.

If not, the system continues down the call stack to Method1, searching for an appropriate handler.

If Method1 has an appropriate catch clause, the system does the following:

Goes back to the top of the call stack—which is Method2

Executes Method2’s finally block and pops Method2 off the stack

Executes Method1’s catch clause and its finally block

If Method1 doesn’t have an appropriate catch clause, the system continues searching down the call stack.

Figure 11-7. Searching down the call stack

308

CHAPTER 11 EXCEPTIONS

General Algorithm

Figure 11-8 shows the general algorithm for handling an exception.

Figure 11-8. The general algorithm for handling an exception

309

CHAPTER 11 EXCEPTIONS

Example of Searching Down the Call Stack

In the following code, Main starts execution and calls method A, which calls method B. A description and diagram of the process are given after the code and in Figure 11-9.

class Program

{

static void Main()

{

MyClass MCls = new MyClass(); try

{ MCls.A(); }

catch (DivideByZeroException e)

{Console.WriteLine("catch clause in Main()"); } finally

{Console.WriteLine("finally clause in Main()"); } Console.WriteLine("After try statement in Main.");

Console.WriteLine("

-- Keep running.");

}

}

class MyClass

{

public void A()

{

try

{ B(); }

catch (System.NullReferenceException)

{Console.WriteLine("catch clause in A()"); } finally

{Console.WriteLine("finally clause in A()"); }

}

void B()

{

int x = 10, y = 0; try

{ x /= y; }

catch (System.IndexOutOfRangeException)

{Console.WriteLine("catch clause in B()"); } finally

{Console.WriteLine("finally clause in B()"); }

}

}

310

CHAPTER 11 EXCEPTIONS

This code produces the following output:

finally clause in B() finally clause in A() catch clause in Main() finally clause in Main()

After try statement in Main.

--Keep running.

1.Main calls A, which calls B, which encounters a DivideByZeroException exception.

2.The system checks B’s catch section for a matching catch clause. Although it has one for

IndexOutOfRangeException, it doesn’t have one for DivideByZeroException.

3.The system then moves down the call stack and checks A’s catch section, where it finds that A also doesn’t have a matching catch clause.

4.The system continues down the call stack and checks Main’s catch clause section, where it finds that Main does have a DivideByZeroException catch clause.

5.Although the matching catch clause has now been located, it is not executed yet. Instead, the system goes back to the top of the stack, executes B’s finally clause, and pops B from the call stack.

6.The system then moves to A, executes its finally clause, and pops A from the call stack.

7.Finally, Main’s matching catch clause is executed, followed by its finally clause. Execution then continues after the end of Main’s try statement.

311

CHAPTER 11 EXCEPTIONS

Figure 11-9. Searching the stack for an exception handler

312

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