В чем польза от броска?а в подвохе? - PullRequest
1 голос
/ 07 января 2012

Из того, что я понимаю throw вызывает исключение.Похоже, что его можно использовать для проверки вашего catch исключения.

  • Каковы преимущества / использование для этого?Почему вы хотите нарочно вызвать исключение?
  • Зачем использовать throw в catch?Похоже, что оно ловит исключение только для того, чтобы снова вызвать исключение.

    try
    {
        //blah
    }
    catch
    {
        throw; 
    }
    

Ответы [ 8 ]

3 голосов
/ 07 января 2012

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

Разница (в языках, которыепозвольте вам просто сказать, что throw;, как в C #), заключается в том, что когда вы перебрасываете исключение, исходная трассировка стека остается в основном нетронутой.(Она включает в себя строку, в которой было переброшено исключение, а не строку, в которой произошло исключение в соответствующем блоке try, но в остальном сохраняется весь след стека.) Если вы говорите throw the_exception_you_caught;, обычно он обрабатывается так, как если бы вы бросилисовершенно новое исключение прямо здесь - существующая трассировка стека стирается, и с этой точки начинается новая.

1 голос
/ 07 января 2012

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

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

Вы можете использовать «бросок» сам по себе в качестве повторного броска. Улов позволяет сделать что-то перед броском. Если мы говорим на C #, проверьте «наконец».

Когда происходит что-то действительно плохое, что не должно происходить, вы можете прервать и сообщить вызывающему, выдав исключение. Это означает, что вам не нужно, чтобы каждый метод возвращал коды результатов и каждый вызывающий вызывающий код проверял коды ошибок / успехов. Он также хорошо описывает, кто обрабатывает такие «исключения», или даже если вы просто оставляете это ОС.

Быстрый ответ ... он упрощает ваш код и дает вам лучший контроль над прерыванием и обработкой исключений. Думайте об этом как о системе обмена сообщениями / прерывания.

1 голос
/ 07 января 2012

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

Более типичное использование будет выглядеть следующим образом:

try {
    // ...
} catch (EmailException ex) {
    SMS.AlertError("Email is not working", ex);
    throw;
}

Если вы throw ex, то исключите такую ​​информацию, как стек вызовов, из исключения.

Функция выше, которая будет:

try {
    // ...
} catch (Exception ex) {
    WorkFlowProblems.Add(new OrderNotSentException("Email did not work", ex));
    View.ShowError("Could not send order!");
}

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

1 голос
/ 07 января 2012

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

try { 
  SomeFunction(); 
} catch { 
  CloseMyResource();
  throw;
}

Преимущество throw против throw exceptionVariable состоит в том, что throw сохраняет исходную трассировку стека.Следующий, кто поймает исключение, увидит исходную трассировку стека.Это в основном для отслеживания ошибок в глубоких стеках вызовов.

1 голос
/ 07 января 2012

Описание

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

Вы можете обработать исключение и сообщить вызывающей стороне, чтоисключение - случайное, а не возвращаемое boolean, указывающее на успешность метода.

Это полезно для модульных тестов и других.

Образец

try
{
    //blah
}
catch
{
    // log exception to textfile of database
    throw; 
}
1 голос
/ 07 января 2012

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

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

0 голосов
/ 07 января 2012

Место, где выбрасывание исключения (на мой взгляд) является НАИБОЛЕЕ полезным, - это когда вы хотите создать экземпляр нового объекта, и существует некоторая вероятность того, что экземпляр должен потерпеть неудачу при создании, и в этом случае экземпляр может быть выполнен для остаются нулевыми (поскольку конструкторы ничего не "возвращают" ... так, например ...

Foo foo = new Foo (); //

// в этой строке foo может быть, а может и не быть тем, что вам нужно, в зависимости от того, какие условия сделали создание Foo возможным.

Итак, Foo выдает исключение, вы можете сделать это:

Foo foo = null;
try{
  foo = new Foo();
}catch(FooException fe){
  //here you can find out if Foo didn't get instantiated as you wanted it to
}

//and here you can test if foo is still null.
0 голосов
/ 07 января 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...