Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Исключения используются для указания того, что при запуске программы произошла ошибка. Объекты исключений, описывающие ошибку, создаются, а затем выбрасываются с помощью инструкции throw или выражения. Затем среда выполнения выполняет поиск наиболее совместимого обработчика исключений.
Программисты должны создавать исключения, если одно или несколько следующих условий являются истинными:
Метод не может осуществить свою определенную функциональность. Например, если параметр метода имеет недопустимое значение:
static void CopyObject(SampleClass original) { _ = original ?? throw new ArgumentException("Parameter cannot be null", nameof(original)); }Неуместный вызов объекта выполняется на основе состояния объекта. Одним из примеров может быть попытка записи в файл, доступный только для чтения. В случаях, когда состояние объекта не разрешает операцию, бросьте экземпляр InvalidOperationException или объект, основанный на производной от этого класса. Следующий код является примером метода, который создает объект InvalidOperationException:
public class ProgramLog { FileStream logFile = null!; public void OpenLog(FileInfo fileName, FileMode mode) { } public void WriteLog() { if (!logFile.CanWrite) { throw new InvalidOperationException("Logfile cannot be read-only"); } // Else write data to the log and return. } }Если аргумент метода вызывает исключение. В этом случае исходное исключение должно быть поймано, и необходимо создать экземпляр ArgumentException. Исходное исключение должно быть передано конструктору ArgumentException в качестве параметра InnerException:
static int GetValueFromArray(int[] array, int index) { try { return array[index]; } catch (IndexOutOfRangeException e) { throw new ArgumentOutOfRangeException( "Parameter index is out of range.", e); } }Заметка
В предыдущем примере показано, как использовать свойство
InnerException. Это намеренно упрощено. На практике необходимо проверить, находится ли индекс в диапазоне перед его использованием. Можно применять эту технику для оборачивания исключения в случаях, когда член параметра выбрасывает исключение, которое невозможно было предвидеть перед вызовом.
Исключения содержат свойство с именем StackTrace. Эта строка содержит имя методов в текущем стеке вызовов вместе с именем файла и номером строки, в котором исключение было создано для каждого метода. Объект StackTrace создается автоматически средой CLR из точки инструкции throw, поэтому исключения должны быть вызваны с точки начала трассировки стека.
Все исключения содержат свойство с именем Message. Эта строка должна быть задана, чтобы объяснить причину исключения. Сведения, конфиденциальные для безопасности, не должны быть помещены в текст сообщения. Помимо Message, ArgumentException содержит свойство с именем ParamName, которое должно быть задано в качестве имени аргумента, вызвавшего исключение. В сеттере свойства ParamName должно быть установлено значение value.
Общедоступные и защищенные методы создают исключения всякий раз, когда они не могут завершить свои предполагаемые функции. Создаваемый класс исключений — это наиболее конкретное исключение, которое соответствует условиям ошибки. Эти исключения должны быть задокументированы как часть функциональных возможностей класса, а производные классы или обновления исходного класса должны сохранять то же поведение для обратной совместимости.
Что следует учитывать при создании исключений
В следующем списке описаны рекомендации, которые следует учитывать при создании исключений:
- Не используйте исключения для изменения потока программы в рамках обычного выполнения. Используйте исключения для создания отчетов и обработки условий ошибок.
- Исключения не следует возвращать как возвращаемое значение или параметр, вместо того чтобы выбрасываться.
- Не выбрасывайте System.Exception, System.SystemException, System.NullReferenceExceptionили System.IndexOutOfRangeException из собственного исходного кода намеренно.
- Не создавайте исключения, которые можно создавать в режиме отладки, но не в режиме выпуска. Чтобы выявлять ошибки во время выполнения на этапе разработки, используйте Debug Assert.
Исключения в методах возврата задач
Методы, объявленные модификатором async, имеют некоторые особые аспекты, когда речь идет об исключениях. Исключения, создаваемые в методе async, хранятся в возвращаемой задаче и не возникают до тех пор, пока, например, задача ожидается. Дополнительные сведения о хранимых исключениях см. в разделе Асинхронные исключения.
Рекомендуется проверить аргументы и вызвать все соответствующие исключения, например ArgumentException и ArgumentNullException, перед вводом асинхронных частей методов. То есть эти исключения проверки должны возникать синхронно перед началом работы. В следующем фрагменте кода показан пример, в котором при возникновении исключений ArgumentException исключения будут синхронно возникать, в то время как InvalidOperationException будут храниться в возвращаемой задаче.
// Non-async, task-returning method.
// Within this method (but outside of the local function),
// any thrown exceptions emerge synchronously.
public static Task<Toast> ToastBreadAsync(int slices, int toastTime)
{
if (slices is < 1 or > 4)
{
throw new ArgumentException(
"You must specify between 1 and 4 slices of bread.",
nameof(slices));
}
if (toastTime < 1)
{
throw new ArgumentException(
"Toast time is too short.", nameof(toastTime));
}
return ToastBreadAsyncCore(slices, toastTime);
// Local async function.
// Within this function, any thrown exceptions are stored in the task.
static async Task<Toast> ToastBreadAsyncCore(int slices, int time)
{
for (int slice = 0; slice < slices; slice++)
{
Console.WriteLine("Putting a slice of bread in the toaster");
}
// Start toasting.
await Task.Delay(time);
if (time > 2_000)
{
throw new InvalidOperationException("The toaster is on fire!");
}
Console.WriteLine("Toast is ready!");
return new Toast();
}
}
Определение классов исключений
Программы могут создавать предопределенный класс исключений в пространстве имен System (за исключением тех, где ранее было указано), или создавать собственные классы исключений, производные от Exception. Производные классы должны определять по крайней мере три конструктора: один конструктор без параметров, один из них задает свойство сообщения и задает свойства Message и InnerException. Например:
[Serializable]
public class InvalidDepartmentException : Exception
{
public InvalidDepartmentException() : base() { }
public InvalidDepartmentException(string message) : base(message) { }
public InvalidDepartmentException(string message, Exception inner) : base(message, inner) { }
}
Добавьте новые свойства в класс исключений, когда предоставленные данные полезны для разрешения исключения. Если новые свойства добавляются в производный класс исключений, ToString() следует переопределить, чтобы вернуть добавленную информацию.
Спецификация языка C#
Дополнительные сведения см. в исключениях и операторе throw в Спецификации языка C#. Спецификация языка является окончательным источником для синтаксиса И использования C#.