




См. Создание и выброс исключений.
При выбрасывании встроенных исключений он говорит:
Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code.
и
Do Not Throw General Exceptions
If you throw a general exception type, such as Exception or SystemException in a library or framework, it forces consumers to catch all exceptions, including unknown exceptions that they do not know how to handle.
Instead, either throw a more derived type that already exists in the framework, or create your own type that derives from Exception."
В этом запись в блоге также есть несколько полезных рекомендаций.
Кроме того, анализ кода FxCop определяет список «не создавать исключения» как описано здесь. Он рекомендует:
The following exception types are too general to provide sufficient information to the user:
- System.Exception
- System.ApplicationException
- System.SystemException
The following exception types are reserved and should be thrown only by the common language runtime:
- System.ExecutionEngineException
- System.IndexOutOfRangeException
- System.NullReferenceException
- System.OutOfMemoryException
Таким образом, теоретически вы можете вызвать любой другой тип исключения фреймворка, если вы четко понимаете цель исключения, как описано Microsoft (см. Документацию MSDN).
Обратите внимание, что это «рекомендации», и, как говорили некоторые другие, вокруг System.IndexOutOfRangeException ведутся споры (т.е. многие разработчики выбрасывают это исключение).
Почему не IndexOutOfRandeException? Что произойдет, если у вас есть средство доступа к индексу (this [int index]) и предоставленное значение выходит за пределы диапазона имеющихся у вас элементов?
Я бы исключил: System.IndexOutOfRangeException, у вас достаточно причин, чтобы выбросить его самостоятельно.
re IndexOutOfRangeException, у меня тоже есть вопрос. Текст взят из связанной статьи.
Я бы бросил IndexOutOfRangeException, когда это возможно. Кажется, что он находится в той же группе, что и ArgumentException, ArgumentNullException и тому подобное, и я не вижу причин не использовать одно из них.
Я думаю, они хотят, чтобы вы использовали System.ArgumentOutOfRangeException вместо System.IndexOutOfRangeException.
@Sekhat Я предполагаю, что в этом сценарии вы должны просто попытаться получить доступ к индексу вместо того, чтобы пытаться проверить и вызвать собственное исключение; вы получите исключение IndexOutOfRangeException, если возникнет проблема.
Вы можете создавать и бросать практически любые из них, но обычно этого делать не следует. Например, различные исключения проверки аргументов (ArgumentException, ArgumentNullException, ArgumentOutOfRangeException и т. д.) Подходят для использования в коде приложения, а AccessViolationException - нет. ApplicationException предоставляется как подходящий базовый класс для любых пользовательских классов исключений, которые могут вам потребоваться.
См. Этот Статья MSDN для списка лучших практик - он относится к обработке исключений, но также содержит полезные советы по их созданию ...
ApplicationException больше не следует использовать в качестве базового класса для настраиваемых исключений. Раньше так было, но Microsoft поняла, что это бесполезно. Используйте Exception как основу для собственных исключений.По поводу System.Exception и System.ApplicationException: последний должен был использоваться в качестве базового класса для всех настраиваемых исключений. Однако это не соблюдалось последовательно с самого начала. Следовательно, существуют разногласия, следует ли вообще использовать этот класс, а не использовать System.Exception в качестве базового класса для всех исключений.
Какой бы способ вы ни выбрали, никогда бросает экземпляр этих двух классов напрямую. На самом деле жаль, что это не abstact. Как бы то ни было, всегда старайтесь использовать наиболее конкретное возможное исключение. Если нет ни одного, отвечающего вашим требованиям, не стесняйтесь создавать свои собственные. Однако в этом случае убедитесь, что ваше исключение имеет преимущество перед существующими исключениями. В частности, он должен идеально передавать его значение и предоставлять всю информацию, необходимую для осмысленного решения ситуации.
Избегайте создания исключений-заглушек, которые не делают ничего значимого. В том же духе избегайте создания огромных иерархий классов исключений, они редко бывают полезными (хотя я могу представить себе ситуацию или две, где я бы их использовал… парсер является одним из них).
Я бы посоветовал сосредоточиться на двух вещах:
Другими словами, я бы сел и определил:
Ответ на первый вопрос, конечно же, зависит от конкретного приложения. Ответ на №2: «То, что делает когда-либо похожий код, с которым они уже знакомы».
В результате получается следующее:
В сценариях, возникающих в ваших программах, которые также поступают в фреймворк, например, аргументы равны нулю, вне диапазона, недействительны, методы не реализуются или просто не поддерживаются, то вам следует использовать те же исключения, что и framework использует. Люди, использующие ваши API, будут ожидать, что они будут вести себя так способ (потому что так ведет себя все остальное), и поэтому будет лучше использовать ваш api с самого начала.
а. Основная цель исключения - человеческое общение. Они передают информация о том, что произошло, чего не должно было быть. Они должны предоставить достаточно информации, чтобы определить причину проблемы и выяснить, как разрешите это.
б. Внутренняя согласованность чрезвычайно важна. Сделать ваше приложение универсальным насколько это возможно при аналогичных обстоятельствах, сделает ваших пользователей API более продуктивными.
Что касается жестких правил о том, что вы должны и не должны делать ... Я бы не стал беспокоиться об этом. Вместо этого я бы просто сосредоточился на идентификации сценариев, нахождении существующего исключения, которое соответствует этим сценариям, а затем на тщательном проектировании вашего собственного, если существующего не существует.