Передача исключений вызывающей стороне

April 7, 2010 by admin Комментировать »

Иногда при возникновении исключения бывает трудно сделать что-либо осмысленное — исключение должно быть обработано вызывающей функцией. Существует три основных сценария: игнорирование, промежуточная обработка и возврат дополнительной информации.

Игнорирование

В первом варианте исключение попросту не перехватывается. Иногда подобное решение оправдано с точки зрения архитектуры программы, однако в результате объект может остаться в неверном состоянии, что вызовет проблемы при его последующем использовании вызывающей стороной. Кроме того, вызывающая сторона не получает достаточной информации о возникшем исключении.

Промежуточная обработка

Во втором варианте исключение перехватывается и после выполнения некоторых операций инициируется заново:

using System;

public class Summer

{

int sum = 0;

int count = 0;

float average;

public void DoAverage()

{

try

{

average = sum / count;

}

catch (DivideByZeroException e)

{

// Выполнить необходимые действия

throw e;

}

}

}

class Test

{

public static void Main()

{

Summer summer = new Summer();

try

{

summer.DoAverage();

}

catch (Exception e)

{

Console.WriteLine("Exception {0}", e);

}

}

}

Обычно в этом варианте действует минимальное требование — в результате обработки исключения объект должен находиться в допустимом состоянии.

Хотя после обработки исключения объект находится в правильном состоянии, вызывающая сторона часто не располагает достаточной информацией для продолжения работы. В нашем случае возникшее исключение говорит о том, что где-то в вызванной функции произошло деление на ноль, но при этом не сообщаются никакие подробности об исключении или способе его исправления.

Если исключение возвращает очевидную информацию, этого может быть вполне достаточно.

Возврат дополнительной информации

В третьем случае пользователю возвращаются дополнительные сведения. Перехваченное исключение «заворачивается» в другое исключение, содержащее новую информацию.

using System;

public class Summer

{

int sum = 0;

int count = 0;

float average;

public void DoAverage()

{

try

{

average = sum / count;

}

catch (DivideByZeroException e)

{

// Создать новое исключение на основе текущего

// и включить в него дополнительную информацию.

throw (new DivideByZeroException(

"Count is zero in DoAverage()", e));

}

}

}

public class Test

{

public static void Main()

{

Summer summer = new Summer();

try

{

summer.DoAverage();

}

catch (Exception e)

{

Console.WriteLine("Exception: {0}", e);

}

}

}

При перехвате DivideByZeroException в функции DoAverage() исключение «заворачивается» в новое исключение, содержащее дополнительную информацию о причине исключения. Обычно исключение-оболочка относится к тому же типу, что и перехваченное исключение, однако в зависимости от модели возможны и другие варианты.

Программа выдает следующий результат:

Exception: System.DivideByZeroException: Count is zero in DoAverage() —>

System.DivideByZeroException

at Summer.DoAverage()

at Summer.DoAverage()

at Test.Main

В идеальном случае каждая функция, заново инициализирующая перехваченные исключения, включает в них дополнительную информацию о контексте.

Оставить комментарий

микросхемы мощности Устройство импульсов питания пример приемника провода витков генератора выходе напряжение напряжения нагрузки радоэлектроника работы сигнал сигнала сигналов управления сопротивление усилитель усилителя усиления устройства схема теория транзистора транзисторов частоты