C #: статья о создании правильного типа исключения - PullRequest
1 голос
/ 31 октября 2010

Иногда я не знаю, какой тип исключения я бы выбрасывал.Поэтому я обычно выкидываю Exception ().Есть ли хорошая статья об этом?

Ответы [ 6 ]

2 голосов
/ 31 октября 2010

«Руководства по проектированию рамок» Квалины и Абрамса действительно хорошо освещают эту тему (ИМХО).

Он доступен бесплатно онлайн здесь , или книга (не бесплатная) здесь (Великобритания) или здесь (США) . Смотрите в разделе, озаглавленном Руководство по разработке исключений .

2 голосов
/ 31 октября 2010

Проблема с генерацией общего исключения заключается в том, что он ограничивает способность вашего кода дальше по стеку обрабатывать его должным образом (т. Е. Перед откатом рекомендуется отлавливать наиболее конкретное возможное исключение и захватывать только то, что вы можете)handle).

У Джеффри Рихтера есть отличный раздел по обработке исключений (включая информацию о пространстве имен System.Exception) в CLR через C #

1 голос
/ 11 апреля 2012

Есть статья Кшиштофа Квалины («Главный архитектор команды .NET Framework в Microsoft») под названием Выбор правильного типа исключения для броска , которая проливает некоторый свет на это. Он касается выбора правильного исключения и инструкций по созданию пользовательских исключений.

1 голос
/ 31 октября 2010

Я бы предложил разделить исключения на несколько категорий в зависимости от состояния системы:

  1. Метод не удался таким образом, что он ничего не делал;состояние любых базовых данных не было нарушено и, вероятно, является действительным.Типичные сценарии: попытка извлечь из коллекции объект, которого там нет, или добавить объект, который уже есть.Другой возможный сценарий: тайм-аут связи в тех случаях, когда он не должен был привести к потере данных (и повторная попытка операции могла бы быть успешной, если проблема была просто в том, что другой конец был просто слишком медленным).
  2. Метод потерпел неудачу способом, который, возможно, нарушил базовую структуру данных или базовая структура данных могла быть повреждена ранее.Не следует предпринимать дальнейшие операции с этой структурой данных, если не предприняты шаги для ее проверки.Другой возможный сценарий: тайм-аут связи происходит, когда запись была частично извлечена, а частично извлеченные данные теперь потеряны.В зависимости от протокола может потребоваться выполнить какое-либо действие по восстановлению соединения или закрыть его и инициировать новое.
  3. Что-то серьезно не так с состоянием системы, и восстановление, скорее всего, невозможно.

К сожалению, существующие исключения .net не соответствуют ничему подобному этому шаблону;было бы неплохо, если бы существовал тип ExceptionBase, из которого были получены такие вещи, как ThreadAbortException, CpuHasCaughtFireException и «нормальное» Exception, а все «нормальные» исключения были получены из Exception.Я понимаю, что .net 4.0 несколько мешает в такой конструкции, но я не знаю точной механики.В любом случае я бы предложил разделить любые пользовательские исключения на группы, как указано выше, причем все исключения в каждой группе имеют общего предка, отличного от других групп.

1 голос
/ 31 октября 2010

Если вы не предпринимаете никаких попыток восстановления после ошибки, вы можете просто выбросить Exception со строкой, чтобы сообщить вам, что пошло не так.(Или если вы будете выполнять одно и то же действие независимо от того, какая ошибка произошла).

Кроме того, что для программиста становится очевидным, что пошло не так, используя новое имя исключения, а не помещая его в Сообщение, и исключение можетсодержат данные, которые помогут вам восстановиться после определенного исключения.

Например, ArgumentNullException имеет свойство ParamName, которое вы должны установить при создании исключения.Когда вызывающий объект улавливает его, он может найти это свойство и принять решение передать новое значение для аргумента, вызвавшего ошибку, или может вывести соответствующую ошибку, чтобы сообщить программисту, что произошло не так.

К сожалению, это не так.что исключения редко используются в полной мере (во многих API с открытым исходным кодом и т. д.) и часто просто вставляются, чтобы сообщить программисту, что пошло не так.Между этими двумя значениями нет большой разницы, если вы не планируете читать свойство ParamName при его обнаружении.(Многие люди не будут беспокоиться, и все равно поймают Exception).

throw new ArgumentNullException("arg1");
throw new Exception("arg1 is null");

Может быть трудно полностью восстановиться после ошибки, но в некоторых приложениях может потребоваться создатьпользовательские исключения, которые могут предоставить всю необходимую вам информацию.

А сейчас я бы просто добавил Exception в поиск объектов Object в VS и посмотрел, что там уже есть.Их имена говорят сами за себя, поэтому вы должны выбрать что-нибудь подходящее.

1 голос
/ 31 октября 2010

Что ж, единственное, что вы не должны делать, это выбросить Exception.
Всегда искать подходящий подкласс.

Я не знаю ни одной публикации, в которой было бы указано, какое исключение следует выбросить.когда, но ArgumentException и InvalidOperationException должны позаботиться о большинстве ваших дел.

Задавать отдельные вопросы об отдельных случаях, если они возникают.

...