Наконец, блок в C# является обязательным?

В чем разница между 2 условиями? Каждый раз, когда выполняется метод method1 или method2, должен быть блок кода, необходимый для запуска. Мне кажется, что 2 метода одинаковы.

// example method1
void Method1(void)
{
    try
    {
        // do something
    }
    catch (Exception ex)
    {
        // do something
    }
    finally
    {
        // do something whenever method1 runs
    }
}

// example method2
void Method2(void)
{
    try
    {
        // do something
    }
    catch (Exception ex)
    {
        // do something
    }

    // do something whenever method2 runs
}

Наконец, блок кажется мне ненужным.

7 ответов

Решение

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

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

Это ключевое слово, чтобы помочь вам с потоком выполнения кода. Когда вы генерируете исключение, это влияет на поток выполнения кода (например, использование return), finally Ключевое слово позволяет вам выразить это, когда возникает исключение (или вы return из try) вы все еще хотите, чтобы казнь сделала что-то, когда она уходит.

Чтобы ответить на вопрос шутливо, это необходимо, когда вам это нужно, а не когда вы этого не делаете.


Дальнейшее чтение

Чтобы быть в безопасности, прежде чем пытаться начать использовать это ключевое слово, прочитайте документацию по нему:

http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

И ключевые слова обработки исключений в целом:

http://msdn.microsoft.com/en-us/library/s7fekhdy.aspx


Примеры

Поймай исключение, чтобы что-то с ним сделать, а затем снова брось. использование finally чтобы вызвать любой код:

try
{
    OpenConnectionToDatabase();
    // something likely to fail
}
catch (Exception ex)
{
    Log(ex);
    throw;  
    // throw ex; // also works but behaves differently
}
// Not specifying an exception parameter also works, but you don't get exception details.
//catch (Exception)
//{
//    Log("Something went wrong);
//    throw;
//}
finally
{
    CloseConnectionToDatabase();
}

Не регистрируйте интерес к ловле исключений, но используйте finally привести в порядок код:

try
{
    OpenConnectionToDatabase();
    // something likely to fail
}
finally
{
    CloseConnectionToDatabase();
}

Возврат от вашего try потому что это выглядит красиво отформатировано, но все еще использовать finally привести в порядок код:

try
{
    OpenConnectionToDatabase();
    return 42;
}
finally
{
    CloseConnectionToDatabase();
}

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

  1. Наконец используется для управления ресурсами. В основном для освобождения ресурсов. Он всегда работает независимо от исключения.
    1. Как мы знаем, catch используется для обработки исключения, но иногда он не может обработать внешнее исключение. Затем блок finally используется для обработки этого исключения для выполнения операции.

Код в блоке finally будет запущен в любом случае после try-catch, он очень полезен для очистки.

try
{
    // open resources
}
catch (Exception ex)
{
    // something bad happened
}
finally
{
    // close resources that are still opened
}

Вам не обязательно иметь finally Блок, тем не менее, наличие этого гарантирует, что код внутри него будет всегда выполняться (если нет исключений в finally!).

Учтите следующее:

void Method2(void) 
{ 
    try 
    { 
        // do something 
    } 
    catch (Exception ex) 
    { 
        // do something 
        throw;
    } 

    // do something whenever method2 runs 
} 

код после try/catch не будет выполняться, если выброшено исключение. Кроме того, если код внутри catch В блоке есть ошибка, которая вызывает исключение (например, запись в журнал выдает непредвиденное исключение) кода, который должен был быть в finally не будет работать, оставив и очистку отменено.

Также return оператор приведет к тому, что этот код не будет запущен, в то время как finally все равно будет выполнено (также здесь вы можете увидеть, что перехват также может быть пропущен, что позволяет любым исключениям распространяться вверх - ПОСЛЕ выполнения finally):

void Method2(void) 
{ 
    try 
    {  
        // do something
        return
    } 
    finally
    {     
        // do something whenever method2 runs 
    }
} 

Всякий раз, когда у вас есть код очистки, который должен быть запущен в конце метода, используйте finally (или если ваши объекты реализуют IDisposable использовать using заявление).

Это будет вести себя очень по-разному в зависимости от того, return от try, например. Так же finally будет работать, даже если catch генерирует исключение (или повторно генерирует исходное исключение), что не произойдет без finally,

Итак: это не обязательно, но будет вести себя иначе. Так что, если вы хотите, чтобы код появился, поместите его в finally,

Во многих отношениях, try/finally гораздо чаще, чем try/catch или же try/catch/finally,

Блок finally гарантирует, что любой код в нем ВСЕГДА будет выполнен, поэтому, если у вас есть оператор return внутри вашего блока try или повторно выдается исключение в вашем блоке catch, код внутри блока finally всегда будет выполняться.

Это необходимо, если вам нужно, чтобы что-то происходило независимо (например, распоряжение ресурсом и т. Д.)

Большая разница в том, что try... catch проглотит исключение, скрывая тот факт, что произошла ошибка. try..finally запустит ваш код очистки, а затем исключение будет продолжаться, чтобы обрабатываться чем-то, что знает, что с ним делать.

Другие вопросы по тегам