- Статья
- Чтение занимает 4 мин
Оператор 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. Тип исключения должен быть как можно более конкретным, чтобы избежать неправильного приема исключений, которые обработчик исключений не сможет разрешить. Таким образом, лучше использовать конкретные исключения вместо базового типа Exception
. Вот несколько примеров.
catch (InvalidCastException e)
{
// recover from exception
}
В одном блоке try-catch можно использовать несколько определенных предложений catch
. В этом случае важен порядок предложений catch
, поскольку предложения catch
проверяются по порядку. Перехватывайте более конкретные исключения перед менее конкретными. Компилятор выдает ошибку, если вы расположили блоки catch в таком порядке, что последующий блок может быть никогда не достигнут.
Использование аргументов catch
представляет один из способов фильтрации исключений, которые требуется обработать. Вы также можете использовать фильтр исключений, который дополнительно проверяет исключение, чтобы решить, следует ли его обрабатывать. Если фильтр исключений возвращает значение false, поиск обработчика продолжается.
catch (ArgumentException e) when (e.ParamName == "…")
{
// recover from exception
}
Фильтры исключений предпочтительнее перехвата и повторного вызова (объясняется ниже), поскольку фильтры оставляют стек в целости и сохранности. Если последующий обработчик разгружает стек, вы можете увидеть, откуда изначально произошло исключение, а не только последнее место, в котором оно было повторно вызвано. Обычно выражения фильтра исключений используются для ведения журнала. Вы можете создать фильтр, который всегда возвращает значение false, а также записывает выходной результат в журнал, чтобы регистрировать исключения в журнале по мере их поступления без необходимости их обработки и повторного вызова.
Оператор throw, включенный в блок catch
, позволяет заново вызвать исключение, перехваченное блоком catch
. В следующем примере извлекаются сведения об источнике из исключения IOException, а затем это исключение вызывается для родительского метода.
catch (FileNotFoundException e)
{
// FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
// Extract some information from this exception, and then
// throw it to the parent method.
if (e.Source != null)
Console.WriteLine("IOException source: {0}", e.Source);
throw;
}
Вы можете перехватывать одно исключение и вызывать другое исключение. При этом следует указать перехватываемое исключение как внутреннее, как показано в следующем примере.
catch (InvalidCastException e)
{
// Perform some action here, and then throw a new exception.
throw new YourCustomException("Put your error message here.", e);
}
Вы также можете повторно вызывать исключение при выполнении указанного условия, как показано в следующем примере.
catch (InvalidCastException e)
{
if (e.Data == null)
{
throw;
}
else
{
// Take some action.
}
}
Примечание
Вы можете использовать фильтр исключений, чтобы получить тот же результат, но проще (при этом не изменяя стек, как описано ранее в этом документе). В следующем примере показано такое же поведение для вызывающих объектов, как и в предыдущем примере. Эта функция отправляет исключение InvalidCastException
обратно вызывающему объекту, если e.Data
имеет значение null
.
catch (InvalidCastException e) when (e.Data != null)
{
// Take some action.
}
В блоке try
инициализируйте только те переменные, которые в нем объявлены. В противном случае до завершения выполнения блока может возникнуть исключение. Например, в следующем примере кода переменная n
инициализируется внутри блока try
. Попытка использовать данную переменную вне этого блока try
в инструкции Write(n)
приведет к ошибке компилятора.
static void Main()
{
int n;
try
{
// Do not initialize this variable here.
n = 123;
}
catch
{
}
// Error: Use of unassigned local variable 'n'.
Console.Write(n);
}
Дополнительные сведения о перехвате исключений см. в разделе try-catch-finally.
Исключения в асинхронных методах
Асинхронный метод помечается модификатором async и обычно содержит одно или несколько выражений или инструкций await. Выражение await применяет оператор await к Task или Task<TResult>.
Когда управление достигает await
в асинхронном методе, выполнение метода приостанавливается до завершения выполнения ожидающей задачи. После завершения задачи выполнение в методе может быть возобновлено. Дополнительные сведения см. в разделе Асинхронное программирование с использованием ключевых слов async и await.
Завершенная задача, к которой применяется await
, может находиться в состоянии сбоя из-за необработанного исключения в методе, который возвращает эту задачу. Ожидание задачи вызывает исключение. Задача также может завершиться в отмененном состоянии, если отменяется асинхронный процесс, возвращающий эту задачу. Ожидание отмененной задачи вызывает OperationCanceledException
.
Для перехвата исключения ожидайте задачу в блоке try
и перехватывайте это исключение в соответствующем блоке catch
. См. пример в разделе Пример асинхронного метода.
Задача может быть в состоянии сбоя, если в ожидаемом асинхронном методе произошло несколько исключений. Например, задача может быть результатом вызова метода Task.WhenAll. При ожидании такой задачи перехватывается только одно из исключений и невозможно предсказать, какое исключение будет перехвачено. См. пример в разделе Пример Task.WhenAll.
Пример
В следующем примере блок try
содержит вызов метода ProcessString
, который может вызвать исключение. Предложение catch
содержит обработчик исключений, который просто отображает сообщение на экране. Когда оператор throw
вызывается из ProcessString
, система осуществляет поиск оператора catch
и отображает сообщение Exception caught
.
class TryFinallyTest
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException(paramName: nameof(s), message: "parameter can't be null.");
}
}
public 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
В следующем примере используются два блока catch и перехватывается наиболее конкретное исключение, поступившее первым.
Чтобы перехватить наименее конкретное исключение, можно заменить оператор throw в ProcessString
следующим оператором: throw new Exception()
.
Если в этом примере первым поместить блок catch для перехвата наименее конкретного исключения, то появится следующее сообщение об ошибке: A previous catch clause already catches all exceptions of this or a super type ('System.Exception')
.
class ThrowTest3
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException(paramName: nameof(s), message: "Parameter can't be null");
}
}
public 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 Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/
Пример асинхронного метода
В следующем примере демонстрируется обработка исключений для асинхронных методов. Для перехвата исключения, вызванного асинхронной задачей, поместите выражение await
в блок try
и перехватывайте это исключение в блоке catch
.
Раскомментируйте строку throw new Exception
в этом примере для демонстрации обработки исключений. Для свойства IsFaulted
задачи установлено значение True
, для свойства Exception.InnerException
задачи установлено это исключение, а исключение перехватывается в блоке catch
.
Раскомментируйте строку throw new OperationCanceledException
, чтобы показать, что происходит при отмене асинхронного процесса. Для свойства IsCanceled
задачи устанавливается значение true
, и исключение перехватывается в блоке catch
. В некоторых условиях, которые неприменимы в данном примере, для свойства IsFaulted
задачи устанавливается значение true
, а для IsCanceled
устанавливается значение false
.
public async Task DoSomethingAsync()
{
Task<string> theTask = DelayAsync();
try
{
string result = await theTask;
Debug.WriteLine("Result: " + result);
}
catch (Exception ex)
{
Debug.WriteLine("Exception Message: " + ex.Message);
}
Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
Debug.WriteLine("Task IsFaulted: " + theTask.IsFaulted);
if (theTask.Exception != null)
{
Debug.WriteLine("Task Exception Message: "
+ theTask.Exception.Message);
Debug.WriteLine("Task Inner Exception Message: "
+ theTask.Exception.InnerException.Message);
}
}
private async Task<string> DelayAsync()
{
await Task.Delay(100);
// Uncomment each of the following lines to
// demonstrate exception handling.
//throw new OperationCanceledException("canceled");
//throw new Exception("Something happened.");
return "Done";
}
// Output when no exception is thrown in the awaited method:
// Result: Done
// Task IsCanceled: False
// Task IsFaulted: False
// Output when an Exception is thrown in the awaited method:
// Exception Message: Something happened.
// Task IsCanceled: False
// Task IsFaulted: True
// Task Exception Message: One or more errors occurred.
// Task Inner Exception Message: Something happened.
// Output when a OperationCanceledException or TaskCanceledException
// is thrown in the awaited method:
// Exception Message: canceled
// Task IsCanceled: True
// Task IsFaulted: False
Пример Task.WhenAll
В следующем примере демонстрируется обработка исключений, когда несколько задач могут привести к нескольким исключениям. Блок try
ожидает задачу, которая возвращается вызовом метода Task.WhenAll. Эта задача завершается после завершения трех задач, к которым применяется WhenAll.
Каждая из трех задач вызывает исключение. Блок catch
выполняет итерацию по исключениям, которые обнаруживаются в свойстве Exception.InnerExceptions
задачи, возвращенной методом Task.WhenAll.
public async Task DoMultipleAsync()
{
Task theTask1 = ExcAsync(info: "First Task");
Task theTask2 = ExcAsync(info: "Second Task");
Task theTask3 = ExcAsync(info: "Third Task");
Task allTasks = Task.WhenAll(theTask1, theTask2, theTask3);
try
{
await allTasks;
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.Message);
Debug.WriteLine("Task IsFaulted: " + allTasks.IsFaulted);
foreach (var inEx in allTasks.Exception.InnerExceptions)
{
Debug.WriteLine("Task Inner Exception: " + inEx.Message);
}
}
}
private async Task ExcAsync(string info)
{
await Task.Delay(100);
throw new Exception("Error-" + info);
}
// Output:
// Exception: Error-First Task
// Task IsFaulted: True
// Task Inner Exception: Error-First Task
// Task Inner Exception: Error-Second Task
// Task Inner Exception: Error-Third Task
Спецификация языка C#
Дополнительные сведения см. в разделе Оператор try в документации Спецификация C# 6.0.
См. также
- Справочник по C#
- Руководство по программированию на C#
- Ключевые слова в C#
- Операторы try, throw и catch (C++)
- throw
- try-finally
- Практическое руководство. Явное создание исключений
Правописание слов «также» и «так же» зависит от того, какая перед нами часть речи. Правило такое: союз пишется слитно, наречие с частицей – раздельно.
Раздельное написание
Правильно писать «так же», если «так» – это наречие, а «же» – частица. Их используют для сравнения объектов.
- Она во всем стремилась походить на подругу: так же ярко красила губы, подолгу крутилась перед зеркалом и манерно растягивала слова.
- Стоял апрель, а на улице все так же хлопьями валил снег.
Подсказка: попробуйте вставить после «так же» словосочетание «как и».
- Так же, как и я, она терпеть не может сливки.
- Животные так же, как и люди, умеют любить.
Слитное написание
«Также» представляет собой союз, который образовался путем сращения наречия с частицей. Писать его нужно слитно.
- Артист нервничал перед выступлением, в зале также ощущалось волнение.
- Доллар, как и евро, также продолжает стремительно расти.
Подсказка: союз «также» можно заменить другим союзом – «и».
- Артист нервничал перед выступлением, и в зале ощущалось волнение.
- И доллар, как евро, продолжает стремительно расти.
Задаем вопрос
Написание слова зависит еще и от вопроса. К наречию с частицей можно задать вопрос «как?». Зато с союзом такой номер не пройдет, поскольку это не самостоятельная часть речи.
Отбрасываем частицу
Рассмотрим такое предложение:
- Мой сегодняшний день прошел так же, как и вчера.
Помня о том, что частица «же» придает лишь эффект усиления, попробуем ее отбросить. Что у нас получилось?
- Мой сегодняшний день прошел так, как и вчера.
Предложение абсолютно не пострадало, значит, в данном случае «так же» следует написать раздельно.
Теперь другой пример:
- Мой друг любит суши и роллы, я также люблю японскую кухню.
Попробуем снова отбросить «же». И вот что у нас получится:
- Мой друг любит суши и роллы, я так люблю японскую кухню.
С предложением явно что-то не то! Еще бы, ведь в этом случае мы отбросили не частицу «же», а оторвали кусочек союза! Запоминаем: в такой ситуации наше слово пишется слитно.
В то же время, если заменить также на тоже – смысл не изменится. Это – убедительный повод для слитного написания.
- Мой друг любит суши и роллы, я тоже люблю японскую кухню.
Синонимы
Наречию с частицей “так же” соответствуют следующие синонимы:
- таким же образом,
- точно так же,
- как и,
- равно как и,
- так же как,
- подобно,
- похоже,
- одинаково,
- аналогично.
Союз “также” можно заменить словами:
- тоже,
- в равной мере,
- вместе с тем,
- равным образом.
Помните о том, что правильно подобранный синоним способен разрешить целый ряд орфографических проблем.
Тяжелый случай
Бывают, правда, непростые ситуации, когда смысл можно определить лишь по широкому контексту, который включает в себя несколько предложений, либо по интонации.
- Девочка была так же очень красивая. (Эта девочка была такая же красивая, как и другая.)
- Настроен он был также решительно. (И настроен он был решительно.)
Пунктуация
Наши слова имеют свои пунктуационные особенности при оформлении на письме. Например, после наречия с частицей «так же» часто следует слово «как». Мы привыкли, что перед «как» обычно ставится запятая. Но это не всегда справедливо. Рассмотрим на примерах:
- Я, так же как и большинство студентов, рассчитываю на стипендию.
(= Я, равно как и большинство студентов, рассчитываю.)
- Я так же, как и большинство студентов, рассчитываю на стипендию.
(= Рассчитываю таким же образом, в такой же степени.)
Надеемся, наша статья помогла вам уяснить разницу между союзом «также» и наречием с частицей «так же». Всегда обращайте внимание на контекст – он поможет разрешить любые трудности. А также не забывайте руководствоваться правилами и подсказками. И на десерт – поучительная лингвистическая сказка.
О силе дружбы
Жили-были на свете наречие Так и частица Же. Так всегда сторонилась Же, потому что считала себя выше нее.
– Я самостоятельное слово! А она кто? – говорило Так вздернув нос.
Же молча сносила обиды и порой даже уходила из предложения, чтобы не оказаться рядом с высокомерным Так. Пожалуй, так бы они никогда и не подружились, если бы не один случай.
Союз И однажды сильно захворал. Настолько, что не мог встать с постели и занять свое законное место в предложении: «И дружба важна для нас». И ведь, как назло, все его ближайшие друзья разъехались – некому было подменить несчастного! Тогда слова решили собрать совет.
– Как же нам быть! Если И не встанет в предложение, оно потеряет смысл!
– Жаль бедолагу. Но мы все можем лишиться работы.
И все слова тихонечко заплакали. Как вдруг Так подошло к Же и опустив голову прошептало:
– Прости меня. Давай дружить. Я знаю, мы сможем помочь.
Же приветливо улыбнулась, протянула Так руку и сказала:
– Дружба также важна для нас.
И тут случилось чудо: предложение обрело смысл! Слова подняли удивленные глаза на бывших врагов и просияли. Они спасены!
С тех пор Так и Же стали такими друзьями, что водой не разольешь. А если и оказывались в предложении порознь, то все равно поддерживали друг друга.
Автор: Садов Артур Александрович, лингвист-типолог
***
© ПишемПравильно.ру
Автор: Садов Артур Александрович, лингвист-типолог
Перечень академических источников, использовавшихся при подготовке материалов.
Правописание этих слов надо знать:
Проверить еще слово:
«Так же» или «также» – слитное и раздельное написание этих словоформ вызывает затруднения. Правописание зависит от используемой части речи и смысловой нагрузки, которую она несет. Как правильно пишется и как научиться распознавать созвучные конструкции в употреблении следует рассмотреть подробнее.
Как правильно пишется: «так же» или «также»?
Оба варианта правильные и согласно орфографическим правилам русского языка применяются в разных случаях.
В зависимости от контекста в предложении используются следующие части речи:
- наречие «так» с частицей «же»;
- союз «также».
Для того чтобы правильно определить часть речи и способ ее написания необходимо поставить к ней вопрос.
В каких случаях пишется «так же»
Наречие «так» с частицей «же» используется в случае утвердительно-сравнительного высказывания. Словосочетание отвечает на вопрос «Как? Каким образом?» Сочетание состоит из самостоятельных слов и пишется всегда раздельно.
Синоним «таким же образом».
Примеры предложений
Для полного понимания следует рассмотреть некоторые примеры.
Когда пишется «также»
Слитное написание характерно для сочинительного союза «также». Он образован путем слияния наречия «так» и частицы «же». Союз не является самостоятельной частью речи и не отвечает на какие-либо вопросы.
Используется в значении приобщения, дополнения к чему-либо. В предложении присоединяет однородные члены или простые предложения в составе сложного.
Примеры предложений
Для более полного понимания следует рассмотреть несколько примеров.
Похожая статья «Вновинку» или «в новинку»: как правильно писать слово?
В каких случаях ставятся запятые?
За сочетанием «так же» часто следует наречие «как». Созданная конструкция отвечает на вопрос «Как?» и выполняет функцию «точного» описания со ссылкой на «первоисточник».
Например:
Выделить эту конструкцию из остальных поможет метод исключения из предложения частицы «же». Смысл сказанного при этом не изменится.
Например:
Я нарисовал замок так (же), как мой сосед, только он был с круглыми окнами.
Он ответил так (же), как Наташа, хотя знал, что ответ неправильный.
В приведенных примерах конструкция без частицы «же» не изменяет смысл.
Правописание союзной конструкции «так же как»
Синтаксическая конструкция, присоединяемая союзом «(точно) так же как (и)» означает сопоставление. Запятая внутри союза (между его частями) не ставится. К нему нельзя задать какие-либо вопросы.
Например:
Сопоставительный союз произносится без пауз. Все части союза пишутся раздельно.
Ошибочное написание слова
Ошибки допускают при неправильном определении слитного и раздельного написания.
В случае узкого контекста трудно определить смысл предложения. Иногда требуется его расширение.
Например:
Остальные также кричали. (И остальные кричали.)
Остальные так же кричали. (Кричали точно так же.)
Созвучность частей речи затрудняет их определение.
Заключение
Чтобы научиться отличать союз от наречия с частицей следует:
- определить контекст, в котором употреблена часть речи;
- задать вопрос (к союзу это сделать невозможно);
- заменить слово синонимом;
- проверить искажение/сохранение смысла сказанного.
Пример анализа.
Света рассказала учителю уважительную причину, почему она не сделала вовремя домашнее задание. Марина также нашла причину, которую можно было считать уважительной.
К анализируемому слову нельзя задать вопрос. Его можно заменить союзом «и» без потери смысла сказанного – И Марина нашла причину. Следовательно, это союз, который пишется слитно.
Мастер попросил токаря выполнить эту работу так же ювелирно. Ему очень понравилось предыдущее изделие.
К анализируемому слову можно задать вопрос «Как?». Его можно заменить синонимом «таким же образом». Следовательно, в предложении наречие с частицей. Написание раздельное.
Предыдущая
Следующая