2009-09-22 8 views
1

Я видел это в устаревшем коде. Что, если таковые имеются, является целью одного броска внутри Catch?В чем смысл этого высказывания Catch?

 Try 
      'Some Oracle access statement 
     Catch err As OracleClient.OracleException 
      Throw 
     Finally 
      'Do something 
     End Try 

Является ли результат таким же, как если бы исходная ошибка не была обнаружена? Не могли бы вы использовать инструкцию Throw без параметров для повторного выброса исходной ошибки, как правило, после выполнения какого-либо действия в первую очередь?

ответ

1

Похоже, он используется для пузырь ошибка вверх. В то время как обычно можно было бы добавить больше в инструкцию catch, чем просто бросить (например, вести журнал, оповещения и т. Д.), В этом случае он позволяет использовать оператор finally для выполнения некоторой очистки, а затем пропускать ошибку до следующего уровня. Без try/catch, как бы этот код очистки был написан в этой области? Как уже упоминалось, синтаксис throw (без ex) сохраняет трассировку стека.

1

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

EDIT

Видимо Exception пузырьков без улова и повторного броска, так что не нужно. Я стою исправлено.

+0

Согласен.Это позволяет исключение, но код finally позволяет вам сделать что-то вроде закрытия соединения или отменить транзакцию, прежде чем передавать исключение обратно вызывающему процессу. – Bomlin

+1

Этот ответ подразумевает, что вы должны иметь улов, чтобы иметь наконец-то, но это не так. :) – jsight

+0

-1 по причине, указанной jsight –

1

Это ничего не делает. Бросьте, как есть правильно.

Вы можете удалить улов, но вы хотите оставить попытку, если в конце есть больше, чем комментарий.

+0

Будут ли возникать исключения, даже если их в блоке try? – Gratzy

+1

Да (не менее 15 символов) – jsight

4

Я часто использовал этот шаблон при отладке; Я поставлю точку останова в выражении throw, чтобы я мог проверить err. Не уверен, есть ли еще одна веская причина сделать это.

1

Он ловит ошибку, затем бросает ее снова. Я не вижу смысла, потому что вы можете сделать Try ... Наконец, без предложения Catch ...

jenningj имеет хороший момент, хотя он мог быть использован для проверки ошибки с точкой останова, но она должна не отображаются в производственном коде.

0

Основная причина использования throw без параметра заключается в том, что он сохранит исходный стек.

Кроме того, вместо на размещение точки останова на утверждение броска, вы могли бы изменили настройки VS разорвать на исключения оракула, то будет гораздо проще, чем добавление точек останова повсюду

3

Многие люди думают, что это не-опера, но это не так. Если у вас есть эта программа:

Module Module1 
    Function Filter() As Boolean 
     Console.WriteLine("1") 
     Return True 
    End Function 

    Sub Thrower() 
     Try 
      Throw New Exception("x") 
     Finally 
      Console.WriteLine("3") 
     End Try 
    End Sub 

    Sub NoCatch() 
     Try 
      Thrower() 
     Finally 
      Console.WriteLine("2") 
     End Try 
    End Sub 

    Sub WithCatch() 
     Try 
      Thrower() 
     Catch ex As Exception 
      Throw 
     Finally 
      Console.WriteLine("2") 
     End Try 
    End Sub 

    Sub Caller(ByVal method As Action) 
     Try 
      method() 
     Catch ex As Exception When Filter() 
     End Try 
    End Sub 

    Sub Main() 
     Console.WriteLine("No Catch") 
     Caller(AddressOf NoCatch) 
     Console.WriteLine("With Catch") 
     Caller(AddressOf WithCatch) 
    End Sub 
End Module 

Выход

No Catch 
1 
3 
2 
With Catch 
3 
1 
2 

Edit: Один сценарий, когда это действительно имеет значение так: Функции Thrower и NoCatch находятся в одной и той же сборки, который ткнули. Метод Caller не является надежным и злонамеренным. Теперь представьте, что метод Thrower использует WindowsIdentity для олицетворения другого пользователя, которого недопустимая сборка не позволяет делать. Затем он полагается на используемый блок (= try/finally), чтобы исключить пользователя, но он выдает исключение. Это означает, что вредоносная сборка выполняется как олицетворенный пользователь во время выполнения метода фильтра. Возможно, это будет работать и при утверждении разрешений, но я не уверен.

+0

Интересно ... но конкретно это что-то изменит? В каком случае был бы важен порядок, в котором называются окончательные предложения? –

+0

Очевидно, что если у вас есть программа, единственная спецификация которой заключается в том, чтобы записать номера 1, 3, 2 на консоль (в указанном порядке) и попытаться решить ее с помощью кода выше :) – erikkallen

+0

Еще одна интересная вещь - фильтры могут в некоторых случаях разрешать регистрировать исключения, которые в конечном итоге будут перезаписаны, даже если их не поймать. 'P1' [in vb.net] вызывает' P2' в 'Catch ZooException Когда ZooFilter()', который вызывает 'P3' в блоке' try/catch MooException'. 'P3' вызывает' P4' в блоке 'try/finally', чье предложение' finally' вызывает 'MooException', а' P4' выдает 'ZooException'. Даже если фильтр в 'P1' видит' ZooException' и решает его поймать, исключение может исчезнуть до того, как оно дойдет до этого. – supercat

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