Поделиться через


Обработка исключений (Руководство по программированию на C#)

Обновлен: Ноябрь 2007

Блок try используется программистами на C# для разделения кода, который может находиться под влиянием исключения, а блоки catch используются для обработки итоговых исключений. Блок finally можно использовать для выполнения кода независимо от возникновения исключения. Такая ситуация необходима в некоторых случаях, поскольку код, следующий после конструкции try/catch не будет выполнен при возникновении исключения. Блок try следует использовать с блоком catch либо finally; в него может входить несколько блоков catch. Пример.

try
{
    // Code to try here.
}
catch (SomeSpecificException ex)
{
    // Code to handle exception here.
    // Only catch exceptions you know how to handle.
    // Never catch base class System.Exception without
    // rethrowing it at the end of the catch block.
}
try
{
    // Code to try here.
}
finally
{
    // Code to execute after try here.
}
try
{
    // Code to try here.
}
catch (SomeSpecificException ex)
{
    // Code to handle exception here.
}
finally
{
    // Code to execute after try (and possibly catch) here.
}

Оператор try без catch или finally вызовет ошибку компилятора.

Блоки catch

Блок catch указывает тип перехватываемого исключения. Этот тип называется фильтром исключений, он должен иметь тип Exception либо быть его производным. Как правило, Exception не задается в блоке catch, если точно не известно, как обрабатывать все исключения, которые могут возникнуть в блоке try, или если оператор throw не включен в конце блока catch.

Несколько блоков catch с различными фильтрами исключений могут быть соединены друг с другом. Вычисление нескольких блоков catch осуществляется сверху вниз, однако для каждого вызванного исключения выполняется только один блок catch. Выполняется первый блок catch, указывающий точный тип или базовый класс созданного исключения. Если блок catch, указывающий соответствующий фильтр исключения, отсутствует, будет выполнен блок catch без фильтра (если таковой имеется). Очень важно, чтобы первыми были размещены блоки catch с самыми конкретными производными классами исключений.

Перехват исключений возможен при выполнении следующих условий.

  • Понимание причины возникновения исключения и реализация особого восстановления, например перехват объекта FileNotFoundException и вывод запроса на ввод нового имени файла.

  • Возможность создания и вызова нового, более конкретного исключения. Пример.

    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch(System.IndexOutOfRangeException e)
        {
            throw new System.ArgumentOutOfRangeException(
                "Parameter index is out of range.");
        }
    }
    
  • Частичная обработка исключения. Например, блок catch можно использовать для добавления записи в журнал ошибок, но затем нужно повторно вызвать исключение, чтобы выполнить его последующую обработку. Пример.

    try
    {
        // try to access a resource
    }
    catch (System.UnauthorizedAccessException e)
    {
        LogError(e);  // call a custom error logging procedure
        throw e;      // re-throw the error
    }
    

Блоки finally

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

Блок finally можно использовать для высвобождения ресурсов, например потоков данных, подключений к базам данных, графических дескрипторов, не ожидая финализации объектов сборщиком мусора в среде выполнения. Дополнительные сведения см. в разделе Оператор using (Справочник по C#).

В этом примере блок finally используется для закрытия файла, открытого в блоке try. Обратите внимание, что состояние дескриптора файла проверяется до его закрытия. Если блок try не открыл файл, дескриптор файла по-прежнему будет иметь значение null. Если файл был успешно открыт и исключение не возникло, блок finally будет выполнен и закроет открытый файл.

System.IO.FileStream file = null;
System.IO.FileInfo fileinfo = new System.IO.FileInfo("C:\\file.txt");
try
{
    file = fileinfo.OpenWrite();
    file.WriteByte(0xF);
}
finally
{
    // check for null because OpenWrite
    // might have failed
    if (file != null)
    {
        file.Close();
    }
}

Спецификация языка C#

Дополнительные сведения см. в следующих разделах документа Спецификация языка C#:

  • 16 Исключения

  • 8.9.5 Оператор throw

  • 8.10 Оператор try

См. также

Основные понятия

Руководство по программированию в C#

Ссылки

Исключения и обработка исключений (руководство по программированию в C#)

try-catch (Справочник по C#)

try-finally (Справочник по C#)

try-catch-finally (Справочник по C#)

Другие ресурсы

Справочник по C#