Подтвердить что ты не робот

Должен ли я ломаться после исключения исключения?

Я пишу пользовательский класс в С#, и я бросаю пару исключений, если люди вводят неверные данные в некоторые из методов. Если выбрано исключение, будет ли выполняться какой-либо из кода в методе после выполнения броска? Должен ли я сделать перерыв после броска, или бросок всегда выходит из метода?

4b9b3361

Ответ 1

Когда вы throw исключаете, следующий код, который нужно выполнить, - это любой блок catch, который охватывает этот бросок внутри метода (если он есть), тогда, окончательно заблокировать (если есть). У вас может быть попытка, try-catch, try-catch-finally или try-finally. Затем, если исключение не обрабатывается, повторно бросается блоком catch или вообще не попадает, управление возвращается вызывающему. Например, вы получите "Yes1, Yes2, Yes3" из этого кода...

try
{
    Console.WriteLine("Yes1");
    throw (new Exception());
    Console.WriteLine("No1");

}
catch
{
    Console.WriteLine("Yes2");
    throw;
    Console.WriteLine("No2");
}
finally
{
    Console.WriteLine("Yes3");
}

Console.WriteLine("No3");

Ответ 2

Throw перемещается вверх по стеку, тем самым выходя из метода.

Ответ 3

Я рекомендую пройти через вашу программу с помощью отладчика, тогда вы сами убедитесь, что происходит. Очень полезно для обучения!

Ответ 4

Я пришел сюда, чтобы найти ответ на оригинальный пост и почти упустил очень ценный ответ, опубликованный Эриком Липпертом. Здесь его ответ размещен в комментариях:

Разделите это на три вопроса.

(1) Будет ли выполняться какой-либо из кода в методе после запуска?
ДА. Если исключение было внутри попытки, тогда будет выполняться код внутри соответствующих блоков catch или finally. Если нет блока try, тогда NO. Управляющие ветки до ближайшего закрывающего фильтра finally, catch или (in vb) блокируют стек.

(2) Должен ли я сделать перерыв после броска?
НЕТ, никогда не делай этого. Конечная точка утверждения throw недоступна; бросок обрабатывается компилятором как goto. Заявление сразу после броска недоступно и никогда не будет выполнено.

(3) Всегда ли бросает метод?
NO. Если бросок находится в попытке и у try есть соответствующий блок catch, тогда блок catch может "съесть" исключение. Только если нет блока catch, исключение делает нелокальное переключение в стек вызовов.

Если у вас есть дополнительные вопросы об этом, я рекомендую прочитать спецификацию С#; все это поведение четко задокументировано.

Наконец, похоже, что вы бросаете "пронзительные" исключения, как в "эй, головорезые, я сказал вам никогда не давать мне эти данные". Это здорово, потому что это предотвращает ошибки в вызывающих. Но если вы это сделаете, вы должны убедиться, что у вызывающего есть какой-то способ узнать, чего вы ожидаете! Если вызывающий абонент не может понять, собираетесь ли вы выбрасывать или нет на основе вашей документации, то вы не сделали исключенного из соображений головокружения, вы сделали неприятное исключение. Подробнее см. http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx.

Ответ 5

Если вы завернули свой код в Try... Catch... Наконец, блок, тогда код под finally всегда будет выполняться. Например:

Try
  ' do some stuff here
  ' Examine user input
  If user input isn't valid
      Throw new exception
Catch
   Throw ' Just re-throws the same exception
Finally
   ' This code will execute, no matter what - exception or not
End Try

Ответ 6

В стороне от вашего фактического вопроса: вы можете переосмыслить использование исключений, чтобы предоставить информацию о проверке обратно пользователю.

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