Существуют ли какие-либо исключения, определенные в .NET Framework, которые я не должен бросать в свой собственный код или что это плохая практика? Должен ли я писать свой собственный?
В С# есть ли встроенные исключения, которые я не должен использовать?
Ответ 1
Вы не должны генерировать исключение, которое автоматически генерируется CLR из-за ошибок пользователя. Например,
- StackOverflowException
- NullReferenceException
- AccessViolationException
- и т.д.
Причина заключается в том, что это создает путаницу для людей, вызывающих ваш API. Пользователи должны иметь возможность различать активно выброшенные исключения API и исключения, которые не активно выбрасываются (вызывается CLR).
Причина в том, что при активном выброшенном исключении обычно представляет собой известное состояние в API. Если я вызываю API и выкидывает ArgumentException, у меня есть разумное ожидание того, что данный объект находится в хорошем состоянии. Он признал потенциально плохую ситуацию и активно учитывал ее. С другой стороны, если он генерирует исключение NullRefrenceException, это указывает на то, что API обнаружил неизвестную ошибку и теперь находится в ненадежном состоянии.
Другая меньшая причина заключается в том, что эти исключения ведут себя по-разному, когда пользовательский код отличается от CLR. Например, можно поймать исключение StackOverflowException, если оно было выведено кодом пользователя, но не было, если оно было выбрано CLR.
РЕДАКТИРОВАТЬ Ответ на комментарий Майкла
Вы также не должны бросать исключение Exception, ApplicationException или SystemException напрямую. Эти типы исключений являются слишком общими для предоставления значимой информации для кода, который вызывает ваш API. Правда, вы можете поместить очень описательное сообщение в параметр сообщения. Но это не прямой или поддерживаемый, чтобы поймать исключение на основе сообщения. Гораздо лучше поймать его по типу.
Правило FxCop на эту тему: http://msdn.microsoft.com/en-us/library/ms182338(VS.80).aspx
Ответ 2
Большинство классов исключений в структуре не предназначены для повторного использования, поскольку они обычно создаются, чтобы сигнализировать о конкретной ошибке Framework. Как и те упомянутые @JaredPar, они используются фреймворком для указания определенных состояний в рамках.
Существует буквально десятки, а может быть сотни, исключения в рамках, поэтому ИМО более полезно перечислять те, которые мы должны использовать. В верхней части моей головы это те, которые я активно использую:
- ArgumentException, ArgumentNullException и ArgumentOutOfRangeException
- InvalidOperationException
- NotSupportedException
- NotImplementedException
Для других условий ошибки в коде пользователя лучше всего создавать свои собственные классы исключений.
Ответ 3
@Michael. На самом деле существует одна ситуация, в которой рекомендуется вызывать исключение NullReferenceException: если первый параметр (параметр "this") метода расширения имеет значение NULL. Вам нужно сделать это, чтобы нулевые переменные велись так, как ожидалось.
Ответ 4
Microsoft в какой-то момент предлагала программистам не наследовать непосредственно из Exception, а вместо этого использовать ApplicationException в качестве своего базового класса. Не уверен, что это мнение по-прежнему сохраняется, хотя...
И если уже существует предопределенное исключение, которое охватывает ваше точное состояние ошибки (например, "NullReferenceException", или "InvalidArgumentException" и т.д.) - всеми средствами бросайте их, а не повторно создавайте их внутри своего собственного кода.
Марк
Ответ 5
для вас существует несколько исключений. Всегда старайтесь использовать эти Исключения перед тем, как перевернуть свои собственные
Ответ 6
Онлайн Руководство по дизайну исключений содержит основные рекомендации (см., в частности, эта страница).
В книге "Руководство по разработке рамок: соглашения, идиомы и шаблоны для многоразовых библиотек .NET, 2-е издание" содержит более подробную информацию и многое другое обсуждение этой темы.