Я пишу пользовательский класс в C#, и я бросаю пару исключений, если люди вводят неверные данные в некоторые из методов. Если выбрано исключение, будет ли выполняться какой-либо из кода в методе после выполнения броска? Должен ли я сделать перерыв после броска, или бросок всегда выходит из метода?Должен ли я ломаться после исключения исключения?
ответ
Исключение составляет следующий код, который должен быть выполнен - это любой блок catch, который охватывает этот бросок внутри метода (если есть), а затем finally block (если есть). У вас может быть попытка, try-catch, try-catch-finally или try-finally. Затем, если исключение не обрабатывается, повторно бросается блоком catch или вообще не попадает, управление возвращается вызывающему. Например, вы получите «Да1, 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");
Это было бы исключение (маленький e) для моего ответа. Я думал о строках исключения, которые будут использоваться в общем контексте и не будут использоваться как оператор GOTO. –
@jarrett: Это обычный контекст, за исключением того, что бросок скрыт внутри вызовов функций. – configurator
Бросок перемещается вверх по стеку, тем самым выходя из метода.
Спасибо. Извините, что задал такой основной вопрос. – Ross
Если вы завернуты код в Try ... Catch ... Наконец-то блокировать, то код под Наконец, это всегда будет выполняться. Например:
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
Как и в сторону, чтобы ваш актуальный вопрос: вы можете пересмотреть использование исключений для предоставления информации проверки обратно пользователю.
Исключение составляет дорогостоящий ресурс и медленный. Если у вас есть несколько правил проверки, которые вам нужно применить, тогда напишите для них конкретный код - вероятно, вы должны полагаться только на обработку исключений для вещей, которые вы не ожидаете.
Мне тоже было интересно об этом. Я пишу класс с высокой оценкой, и конструктор может принимать параметр «max». что указывает на максимальную оценку. хорошо, если они передают число, большее, чем поддержка моего класса, я выбрасывал исключение, потому что я не хотел, чтобы конструктор закончил с плохой информацией. Я новичок в этом, есть ли лучший способ сделать это? – Ross
Это комментарий, а не ответ на ОП. – Drellgor
Я рекомендую вам пройти через вашу программу с помощью отладчика, тогда вы сами убедитесь, что происходит. Очень полезно для обучения!
Я пришел сюда, чтобы найти ответ на исходное сообщение и почти упустил очень ценный ответ, отправленный Eric Lippert. Вот его ответ, размещенный в комментариях:
Разделите это на три вопроса.
(1) Будет ли выполнен какой-либо код в методе после выполнения броска?
ДА. Если исключение было внутри попытки, тогда будет выполняться код внутри соответствующих блоков catch или finally. Если нет блока try, тогда NO. Управляющие ветви к ближайшему окружному фильтру finally, catch или (in vb) исключают блокировку стека.
(2) Должен ли я сделать перерыв после броска?
НЕТ, никогда не делайте этого. Конечная точка утверждения throw недоступна; бросок обрабатывается компилятором как goto. Заявление сразу после броска недоступно и никогда не будет выполнено.
(3) Бросает ли всегда метод?
NO. Если бросок находится в попытке и у try есть соответствующий блок catch, тогда блок catch может «съесть» исключение. Только если нет блока catch, исключение выполняет нелокальное переключение стека вызовов.
Если у вас есть дополнительные вопросы по этому вопросу, я рекомендую прочитать спецификацию C#; все это поведение четко задокументировано.
Наконец, звучит так, будто вы бросаете «пронзительные» исключения, как в «эй, головорезые, я сказал вам никогда не давать мне эти данные». Это здорово, потому что это предотвращает ошибки в вызывающих. Но если вы это сделаете, вы должны убедиться, что у вызывающего есть какой-то способ узнать, чего вы ожидаете! Если вызывающий абонент не может понять, собираетесь ли вы выбрасывать или нет на основе вашей документации, то вы не сделали исключенного из соображений головокружения, вы сделали неприятное исключение. См. http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx.
Что касается вашего первого момента: у C# теперь есть фильтры исключений; это не только для VB. –
Разделите это на три вопроса. (1) Будет ли выполняться какой-либо код в методе после запуска? ДА. Если исключение было внутри попытки, тогда будет выполняться код внутри соответствующих блоков catch или finally. Если нет блока try, тогда NO. Управляющие ветви к ближайшему окружному фильтру finally, catch или (in vb) исключают блокировку стека. –
(2) Должен ли я сделать перерыв после броска? НЕТ, никогда не делай этого. Конечная точка утверждения throw недоступна; бросок обрабатывается компилятором как goto. Заявление сразу после броска недоступно и никогда не будет выполнено. –
(3) Всегда ли бросает метод? NO. Если бросок находится в попытке и у try есть соответствующий блок catch, тогда блок catch может «съесть» исключение. Только если нет блока catch, исключение выполняет нелокальное переключение стека вызовов. –