try-catch (Справочник по C#)
Обновлен: Ноябрь 2007
Инструкция try-catch состоит из блока try, за которым следует одно или несколько предложений catch, в которых определяются обработчики для различных исключений. При возникновении исключения среда CLR ищет оператор catch, который обрабатывает это исключение. Если выполняющийся в данный момент метод не содержит такого блока catch, то среда CLR рассматривает метод, который вызвал текущий метод, и т. д. по стеку вызовов. Если блок catch не найден, то среда CLR отображает пользователю сообщение о необработанном исключении и останавливает выполнение программы.
Блок try содержит защищаемый код, в котором могут происходить исключения. Этот блок выполняется до момента возникновения исключения или до своего успешного завершения. Например, следующая попытка приведения объекта null вызовет исключение NullReferenceException.
object o2 = null;
try
{
int i2 = (int)o2; // Error
}
Хотя предложение catch можно использовать без аргументов для перехвата любого типа исключения, такой подход не рекомендуется. В общем случае следует перехватывать только те исключения, устранение причин которых известно. Поэтому следует всегда задавать аргумент объекта, производного от System.Exception. Например:
catch (InvalidCastException e)
{
}
В одной и той же инструкции try-catch можно использовать несколько предложений catch. В этом случае будет иметь значение порядок следования предложений catch, поскольку предложения catch будут проверяться именно в этом порядке. Более общие исключения следует перехватывать после более частных. При упорядочивании блоков catch таким образом, чтобы последующий блок был недостижимым, компилятор вызовет ошибку.
В блок catch можно включить инструкцию throw, чтобы заново создать исключение, перехваченное в предложении catch. Пример.
catch (InvalidCastException e)
{
throw (e); // Rethrowing exception e
}
Также можно создать новое исключение. При этом задайте исключение, захваченное в качестве внутреннего исключения:
catch (InvalidCastException e)
{
// Can do cleanup work here.
throw new CustomException("Error message here.", e);
}
Если требуется заново создать исключение, обрабатываемое предложением catch без параметров, используйте инструкцию throw без аргументов. Пример.
catch
{
throw;
}
Внутри блока try следует инициализировать только те переменные, которые создаются в этом блоке. В противном случае исключение может возникнуть до завершения блока. Например, в следующем примере кода переменная x инициализируется внутри блока try. Попытка использовать эту переменную вне блока try в инструкции Write(x) приведет к ошибке компиляции: Использование локальной переменной x, которой не присвоено значение.
static void Main()
{
int x;
try
{
// Don't initialize this variable here.
x = 123;
}
catch
{
}
// Error: Use of unassigned local variable 'x'.
Console.Write(x);
}
Дополнительные сведения о перехвате исключений см. в разделе try-catch-finally.
Пример
В этом примере блок try содержит обращение к методу ProcessString, который может вызвать исключение. В предложении catch содержится обработчик исключения, который просто выводит на экран сообщение. Если инструкция throw вызывается из метода MyMethod, система осуществляет поиск инструкции catch и выводит на экран сообщение Exception caught.
class TryFinallyTest
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}
static void Main()
{
string s = null; // For demonstration purposes.
try
{
ProcessString(s);
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at TryFinallyTest.Main() Exception caught.
* */
В этом примере используются две инструкции catch. Срабатывает первая из них, которая принимает более узкий диапазон исключений.
class ThrowTest3
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}
static void Main()
{
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (ArgumentNullException e)
{
Console.WriteLine("{0} First exception caught.", e);
}
// Least specific:
catch (Exception e)
{
Console.WriteLine("{0} Second exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at TryFinallyTest.Main() First exception caught.
*/
Если в предыдущем примере поменять местами предложения catch, появится следующее сообщение об ошибке.
A previous catch clause already catches all exceptions of this or a super type ('System.Exception')
Если же требуется перехватить исключение, относящееся к более широкому диапазону, необходимо изменить инструкцию throw следующим образом.
throw new Exception();
Спецификация языка C#
Дополнительные сведения см. в следующих разделах документа Спецификация языка C#:
5.3.3.13 Инструкции try-catch
8.10 Инструкция try
16 Исключения
См. также
Задачи
Практическое руководство. Явное создание исключения
Основные понятия
Руководство по программированию в C#
Ссылки
The try, catch, and throw Statements
Операторы обработки исключений (Справочник по C#)
try-finally (Справочник по C#)