Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Блок 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
может указать тип исключения для перехвата. Спецификация типа называется фильтром исключений. Тип исключения должен быть производным от Exception. Как правило, не указывайте Exception в качестве фильтра исключений, если вы не знаете, как обрабатывать все исключения, которые могут быть вызваны в try
блоке, или если вы добавили инструкцию throw
в конце блока catch
.
Несколько catch
блоков с разными классами исключений можно объединить. Блоки catch
вычисляются сверху вниз в коде, но для каждого исключения, которое создается, выполняется только один catch
блок.
catch
Первый блок, указывающий точный тип или базовый класс создаваемого исключения, выполняется. Если ни один блок catch
не указывает соответствующий класс исключений, будет выбран блок catch
, который не имеет типа, если такой блок присутствует в инструкции. Важно сначала разместить catch
блоки с наиболее конкретными классами исключений (т. е. наиболее производными).
Перехватывайте исключения, если выполняются следующие условия:
- У вас есть хорошее представление о том, почему исключение может быть создано, и вы можете реализовать определенное восстановление, например предложить пользователю ввести новое имя файла при перехвате FileNotFoundException объекта.
- Вы можете создать и бросить новое, более конкретное исключение.
int GetInt(int[] array, int index) { try { return array[index]; } catch (IndexOutOfRangeException e) { throw new ArgumentOutOfRangeException( "Parameter index is out of range.", e); } }
- Вы хотите частично обработать исключение перед его передачей для дальнейшей обработки. В следующем примере блок
catch
используется для добавления записи в журнал ошибок перед перебросом исключения.try { // Try to access a resource. } catch (UnauthorizedAccessException e) { // Call a custom error logging procedure. LogError(e); // Re-throw the error. throw; }
Можно также указать фильтры исключений , чтобы добавить логическое выражение в предложение catch. Фильтры исключений указывают, что конструкция catch срабатывает только в том случае, если условие истинно. В следующем примере оба предложения catch используют один и тот же класс исключений, но для создания другого сообщения об ошибке проверяется дополнительное условие:
int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch (IndexOutOfRangeException e) when (index < 0)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be negative.", e);
}
catch (IndexOutOfRangeException e)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be greater than the array size.", e);
}
}
Фильтр исключений, который всегда возвращается false
, можно использовать для проверки всех исключений, но не обработки их. Обычно используется журнал исключений:
public class ExceptionFilter
{
public static void Main()
{
try
{
string? s = null;
Console.WriteLine(s.Length);
}
catch (Exception e) when (LogException(e))
{
}
Console.WriteLine("Exception must have been handled");
}
private static bool LogException(Exception e)
{
Console.WriteLine($"\tIn the log routine. Caught {e.GetType()}");
Console.WriteLine($"\tMessage: {e.Message}");
return false;
}
}
Метод LogException
всегда возвращает false
, ни одно предложение с использованием этого фильтра исключений не соответствует. Предложение catch может быть общим, используя System.Exception, и последующие предложения могут обрабатывать более конкретные классы исключений.
Наконец, блоки
Блок finally
позволяет очистить действия, выполняемые в блоке try
. Если блок finally
присутствует, он выполняется последним, после блока try
и любого соответствующего блока catch
.
finally
блок всегда выполняется: возникает ли исключение или обнаружен catch
блок, соответствующий типу исключения.
Этот finally
блок можно использовать для освобождения таких ресурсов, как потоки файлов, подключения к базе данных и графические дескрипторы, без ожидания завершения объектов сборщиком мусора в среде выполнения.
В следующем примере finally
блок используется для закрытия файла, открываемого в блоке try
. Обратите внимание, что состояние дескриптора файла проверяется до закрытия файла.
try
Если блок не может открыть файл, дескриптор файла по-прежнему имеет значениеnull
, и finally
блок не пытается закрыть его. Вместо этого, если файл успешно открыт в блоке try
, finally
блок закрывает открытый файл.
FileStream? file = null;
FileInfo fileinfo = new System.IO.FileInfo("./file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Check for null because OpenWrite might have failed.
file?.Close();
}
Спецификация языка C#
Дополнительные сведения см. в разделе "Исключения " и инструкции try в спецификации языка C#. Спецификация языка является авторитетным источником синтаксиса и использования языка C#.