Мысли о блоках try-catch - PullRequest
       34

Мысли о блоках try-catch

6 голосов
/ 15 апреля 2009

Что вы думаете о коде, который выглядит следующим образом:

public void doSomething()
{
    try
    {
       // actual code goes here
    }
    catch (Exception ex)
    {
        throw;
    }
}

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

Итак, мой вопрос, почему это было бы хорошо?

---- РЕДАКТИРОВАТЬ ----

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

Ответы [ 10 ]

15 голосов
/ 15 апреля 2009

В зависимости от того, какое качество вы смотрите, оно не бросает исключение в другое место. «throw» без цели сбрасывает исключение, которое очень отличается от броска исключения. Прежде всего, повторный выброс не сбрасывает трассировку стека.

В этом конкретном примере выгода бессмысленна, потому что она ничего не делает. Исключение счастливо переброшено, и это почти как если бы попытка / улов не существовала.

3 голосов
/ 15 апреля 2009

Не было бы, в идеале, блок catch мог бы выполнить некоторую обработку, а затем сбросить, например,

try
{
    //do something
}
catch (Exception ex)
{
    DoSomething(ex); //handle the exception
    throw;
}

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

3 голосов
/ 15 апреля 2009

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

Примите во внимание, что бросить; отличается от бросить экс;

throw ex урезает стек до новой точки броска, теряя ценную информацию об исключении.

public void doSomething()
{
    try
    {
       // actual code goes here
    }
    catch (EspecificException ex)
    {
        HandleException(ex);
    }
    catch (Exception ex)
    {
        throw;
    }
}
1 голос
/ 15 апреля 2009

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

public void doSomething()
{
    try
    {
       // actual code goes here
    }
    catch (Exception ex)
    {
        LogException (ex);  // Log error...
        throw;
    }
}
1 голос
/ 15 апреля 2009

Делать что-то подобное довольно бессмысленно, и в целом я стараюсь не идти по пути делать бессмысленные вещи;)

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

0 голосов
/ 15 апреля 2009

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

Полная статья о том, почему, смотрите " Релиз НЕ ОТЛАДАН: 64-битная оптимизация и встраивание методов C # в стеки вызовов сборки выпуска " Скотт Хансельман

0 голосов
/ 15 апреля 2009

Не думаю, что просто сбросить ошибку было бы полезно. Если вы действительно не заботитесь об ошибке в первую очередь.

Я думаю, что было бы лучше сделать что-то в улове.

Вы можете проверить Руководство по обработке исключений MSDN .

0 голосов
/ 15 апреля 2009

Зависит от того, что вы подразумеваете под «выглядит так», и если в блоке catch нет ничего, кроме повторного броска ... если это так, то попытка catch не имеет смысла, за исключением, как вы говорите, запутывания где исключение произошло. Но если вам нужно что-то сделать прямо там, где произошла ошибка, но вы хотите обработать исключение в стеке, это может быть уместно. Но тогда улов будет для конкретного исключения, которое вы обрабатываете, а не для любого исключения

0 голосов
/ 15 апреля 2009

Ну, для начала я бы просто сделал

catch
{
   throw;
}

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

, например

catch(SQLException sex) //haha
{
   DoStuff(sex);
}
catch
{
   throw;
}
0 голосов
/ 15 апреля 2009

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

Разница между этим и тем, что вы говорите, состоит в том, что эти пользовательские объекты Exception содержат БОЛЬШЕ информации о фактическом произошедшем исключении, а не меньше.

...