Использование блока finally

Иногда требуется определить кодовый блок, который будет выполняться после выхода из блока try/catch. В частности, исключительная ситуация может возникнуть в связи с ошибкой, приводящей к преждевременному возврату из текущего метода. Но в этом методе мог быть открыт файл, который нужно закрыть, или же установлено сетевое соединение, требующее разрывания. Подобные ситуации нередки в программировании, и поэтому для их разрешения в C# предусмотрен удобный способ: воспользоваться блоком finally.

Для того чтобы указать кодовый блок, который должен выполняться после блока try/catch, достаточно вставить блок finally в конце последовательности операторов try/catch. Ниже приведена общая форма совместного использования блоков try/catch и finally.

try {

  // Блок кода, предназначенный для обработки ошибок.

}

catch (ExcepTypel exOb) {

  // Обработчик исключения типа ExcepTypel.

}

.

.

.

catch (ЕхсерТуре2 ехОb) {

  // Обработчик исключения типа ЕхсерТуре2. }

finally {

  // Код завершения обработки исключений.

}

Блок finally будет выполняться всякий раз, когда происходит выход из блока try/catch, независимо от причин, которые к этому привели. Это означает, что если блок try завершается нормально или по причине исключения, то последним выполняется код, определяемый в блоке finally. Блок finally выполняется и в том случае, если любой код в блоке try или в связанных с ним блоках catch приводит к возврату из метода.

Ниже приведен пример применения блока finally.

// Использовать блок finally.

using System;

class UseFinally {

  public static void GenException(int what) {

    int t;

    int[] nums = new int [2];

    Console.WriteLine("Получить " + what);

    try {

      switch(what) {

      case 0:

        t = 10 / what; // сгенерировать ошибку из-за деления на нуль

        break;

      case 1:

        nums[4] =4; // сгенерировать ошибку индексирования массива

        break;

      case 2:

        return; // возврат из блока try

      }

    }

    catch (DivideByZeroException) {

      Console.WriteLine("Делить на нуль нельзя!");

      return; // возврат из блока catch

    }

    catch (IndexOutOfRangeException) {

      Console.WriteLine("Совпадающий элемент не найден.");

    }

    finally {

      Console.WriteLine("После выхода из блока try.");

    }

  }

}

class FinallyDemo {

  static void Main() {

    for(int i=0; i < 3; i++) {

      UseFinally.GenException(i);

      Console.WriteLine() ;

    }

  }

}

Вот к какому результату приводит выполнение этой программы.

Получить 0

Делить на нуль нельзя

После выхода из блока try.

Получить 1

Совпадающий элемент не найден.

После выхода из блока try.

Получить 2

После выхода из блока try.

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

И еще одно замечание: с точки зрения синтаксиса блок finally следует после блока try, и формально блоки catch для этого не требуются. Следовательно, блок finally можно ввести непосредственно после блока try, опустив блоки catch. В этом случае блок finally начнет выполняться сразу же после выхода из блока try, но исключения обрабатываться не будут.