Наконец, блок в 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, всегда выполняется. Пожалуйста, обратите внимание на следующий пункт, написанный ниже, он очистит вас от путаницы.
- Наконец используется для управления ресурсами. В основном для освобождения ресурсов. Он всегда работает независимо от исключения.
- Как мы знаем, 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 запустит ваш код очистки, а затем исключение будет продолжаться, чтобы обрабатываться чем-то, что знает, что с ним делать.