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

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

Следующие примеры показывают операторы try-catch, try-finally и try-catch-finally.

try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
    // Only catch exceptions that 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 goes here.
}
finally
{
    // Code to execute after the try block goes here.
}
try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
}
finally
{
    // Code to execute after the try (and possibly catch) blocks 
    // goes here.
}

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

Блоки catch

Блок catch может указывать тип перехватываемого исключения.Спецификация типа называется фильтр исключений.Тип исключения должны быть унаследован от Exception.Как правило, не следует задавать Exception в качестве фильтра исключений, кроме случаев, когда известно, как обрабатывать все исключения, которые могут быть созданы в блоке 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)
    {
        // Call a custom error logging procedure.
        LogError(e);
        // Re-throw the error.
        throw;     
    }
    

Блоки finally

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

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

В следующем примере с помощью блока finally закрывается файл, открытый в блоке try.Обратите внимание, что состояние дескриптора файла проверяется до закрытия файла.Если блок try не может открыть этот файл, дескриптор файла по-прежнему имеет значение null и блок finally не пытается закрыть его.Кроме того, если файл успешно открыт в блоке try, блок 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#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

См. также

Ссылки

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

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

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

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

Оператор using (Справочник по C#)

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

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

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

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