2010-04-28 2 views
50

Можно создать дубликат:
difference between throw and throw new Exception()Что делает «бросок»? сам по себе делаете?

Что бы точка просто с

catch (Exception) 
{ 
    throw; 
} 

Что это делать?

+0

Возможный дубликат [разница между throw и throw new Exception()] (http://stackoverflow.com/q/2999298/) и [разница между try/catch/throw и try/catch (e)/throw е] (http://stackoverflow.com/q/1697216/). –

ответ

80

Само по себе ключевое слово throw просто заново исключает исключение, задокументированное вышеприведенным заявлением catch. Это удобно, если вы хотите выполнить некоторую рудиментарную обработку исключений (возможно, компенсирующее действие, подобное откату транзакции), а затем перестроить исключение на вызывающий метод.

Этот метод имеет одно существенное преимущество перед улавливанием исключения в переменной и метать этот экземпляр: он сохраняет исходный стек вызовов. Если вы поймаете (Exception ex) и затем выбросите ex, ваш стек вызовов начнется только с этого оператора throw, и вы потеряете метод/строку исходной ошибки.

+0

Как я понимаю, все содержимое блока 'catch' является' throw; ', поэтому никакой дополнительной обработки исключений не возникает. Хотя я могу ошибаться. – Gorpik

+0

Каков ответ вашей реакции на точку boris? – CJ7

+0

Борис прав, поскольку представленный пример на самом деле ничего не делает, но я не думаю, что в стек вызовов есть какие-либо изменения. –

3

Он повторяет ту же ошибку, вы ничего не получаете от этого.
Иногда вы можете использовать метод поймать, чтобы сделать некоторые протоколирование или что-то не interupting вашего исключения, как это:

catch (Exception) { 
    myLogger.Log(LogLevels.Exception, "oh noes!") 
    throw; 
} 

Первоначально я mistakingly думал, что это будет раскручивать свой стек, но это будет только тогда, когда вы могли бы сделать следующее :

catch (Exception err) { 
    throw err; 
} 
+0

Вы уверены, что у вас есть лишний стек, потому что использование «броска» в одиночку просто перевернет исходное исключение с точным стеклом в качестве оригинала ... правильно ?! – veggerby

+0

@boris: вы говорите, что какой-то код будет исполнен дважды? – CJ7

+0

@Veggerby: Вы правы, я сбивал с толку случай, когда вы говорите «catch» (Exception ex) {throw ex}. В случае кода вопроса ничего не происходит. @Craig: ничего не запускается дважды –

3

Единственная причина, по которой я могу думать, это если вы хотите поставить точку останова во время отладки.
Это также код по умолчанию, создаваемый некоторыми инструментами, которые я думаю.

11

Иногда вы можете захотеть сделать что-то вроде этого:

try 
{ 
    // do some stuff that could cause SomeCustomException to happen, as 
    // well as other exceptions 
} 
catch (SomeCustomException) 
{ 
    // this is here so we don't double wrap the exception, since 
    // we know the exception is already SomeCustomException 
    throw; 
} 
catch (Exception e) 
{ 
    // we got some other exception, but we want all exceptions 
    // thrown from this method to be SomeCustomException, so we wrap 
    // it 
    throw new SomeCustomException("An error occurred saving the widget", e); 
} 
+2

+1 потому что новый бросок проходит оригинальное исключение - очень, очень важно (-: – Murph

2

Просто повторно выдать текущее исключение, и это исключение будет держать его «источник» и трассировки стека.

Смежные вопросы