Подтвердить что ты не робот

Почему это "наконец" выполняется?

Если вы запустите код ниже, он фактически выполнит окончательно после каждого вызова goto:

    int i = 0;
Found:
    i++;
    try
    {
        throw new Exception();
    }
    catch (Exception)
    {
        goto Found;
    }
    finally
    {
        Console.Write("{0}\t", i);
    }

Почему?

4b9b3361

Ответ 1

Почему вы ожидаете, что он не будет выполнен?

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

Вместо goto, рассмотрите "return".

//imagine this try/catch/finally block is inside a function with return type of bool. 
try
{
    throw new Exception();
}
catch (Exception)
{
    return false; //Let say you put a return here, finally block still executes.
}
finally
{
    Console.WriteLine("I am in finally!");
}

Ответ 2

Следующий текст исходит из Спецификации языка С# (8.9.3 Операция goto)


Оператор goto выполняется следующим образом:

  • Если оператор goto выходит из одного или нескольких блоков try с связанными блоками finally, управление сначала переносится в блок finally самого внутреннего заявления try. Когда и если управление достигает конечной точки блока finally, управление передается блоку finally следующего прилагаемого оператора try. Этот процесс повторяется до тех пор, пока не будут выполнены окончательные блоки всех промежуточных операторов try.
  • Контроль передается цели оператора goto.

Ответ 3

Суть приведенных ответов - что, когда управление покидает защищенную область любыми способами, будь то "возврат", "переход", "разрыв", "продолжение" или "бросок", выполняется "наконец" - верный. Тем не менее, я отмечаю, что почти каждый ответ говорит что-то вроде "блок finally всегда работает". Блок finally НЕ всегда запускается. Есть много ситуаций, в которых блок finally не запускается.

Кто хочет попытаться перечислить их все?

Ответ 4

Кажется разумным. Блок finally всегда запускается после try или catch.

Аналогично

try
{
  // do something
  return;
}
finally
{
  // do something else
}

всегда будет запускать блок finally. EDIT - но см. Комментарии Эрика выше.

Ответ 5

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

Ответ 6

Как уже упоминалось, finally работает независимо от потока программы. Конечно, блок finally не является обязательным, поэтому, если он вам не нужен, не используйте его.

Ответ 7

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

Ответ 8

Это точка блока finally. Он всегда выполняется (в значительной степени).