Подтвердить что ты не робот

Как выбрать наиболее подходящий тип исключения для броска?

Уже есть много вопросов о SO об исключениях, но я не могу найти ответ на мой вопрос. Не стесняйтесь указать мне в сторону другого вопроса, если я пропустил его.

Мой вопрос довольно прост: как другие разработчики (С#) приходят к выбору наиболее подходящего типа исключения для броска? Раньше я написал следующий код:

    if (Enum.IsDefined(enumType, value))
    {
        return (T)Enum.Parse(enumType, value);
    }
    else
    {
        throw new ArgumentException(string.Format("Parameter for value \"{0}\" is not defined in {1}", value, enumType));
    }

С тех пор я понял, что выбрасывание InvalidEnumArgumentException, вероятно, было бы более подходящим, если бы я знал о его существовании в то время.

Имеется ли доступный авторитетный ресурс, который помогает разработчикам выбирать типы исключений, или это просто вопрос опыта?

Изменить

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

4b9b3361

Ответ 1

Я бы сказал, что это просто для того, чтобы испытать. Есть все еще новые исключения, которые я обнаруживаю каждый так часто, и я уже давно работаю со многими аспектами .NET. Что бы вы хотели, чтобы этот источник вам рассказывал? Выбор подходящего типа исключений может показаться весьма контекстно-зависимым, поэтому я сомневаюсь в том, какой уровень советов он может предложить. Листинг более распространенных будет больше всего, что он мог бы предоставить. Имена и описания Intellisense типов исключений обычно с хорошей ясностью объясняют их сценарии использования.

Моя рекомендация - просто ознакомиться со всеми основными (в частности, те, что указаны в System, System.IO и любых других пространствах имен, которые вы часто используете), и изучать другие на этом пути. Я нахожу, что я вообще убираюсь с помощью небольшого количества. Если вы случайно используете более общий тип исключения, если в BCL уже существует более конкретный, то это не является большим преступлением и может быть изменено позже достаточно легко. Если честно, для какой-либо ошибки, которая особенно специфична, вам часто понадобится создать свой собственный класс, наследующий от Exception в любом случае.

Надеюсь, что это поможет.

Изменить: Если вы хотите получить краткое руководство по очень распространенным, см. страницу Общие классы исключений на MSDN.

Ответ 2

Krzysztof Cwalina имеет хороший пост на этом см. главу "1.1.1 Выбор правильного типа исключения для броска"

PS Обсудите подписку на свой блог. Хорошее чтение!

Чтобы ответить на ваш вопрос: InvalidEnumArgumentException
потому что бросают наиболее конкретное (наиболее производное) исключение, которое имеет смысл.

И вызывающие, которые улавливают ArgumentException, ловят InvalidEnumArgumentException тоже...

Ответ 3

Общие типы исключений и их пояснения

Я думаю, что это, вероятно, поможет вам узнать, какие наиболее подходящие исключения для вас использовать. Вы также можете заглянуть в документацию MSDN для получения дополнительной информации о классе Exception и всех его типах, если вам нужно.

Ответ 4

Если вы посмотрите статью MSDN в System.Exception, в нижней части страницы находится целый список типов исключений BCL которые наследуют Исключение. Это не совсем окончательный список того, что следует использовать для чего - но это дает вам отличное место, чтобы начать проверку типов исключений. Прохождение каждого из них подскажет, для чего они должны использоваться:

Существует также довольно обширная статья об иерархии исключений .NET, найденная по адресу:

На самом деле весь раздел в библиотеке MSDN об обработке и метании исключений довольно хорош:

Ответ 5

Я думаю, что реальный вопрос заключается в том, чтобы спросить себя: "Какого типа исключения я хочу обработать?" Если вы не будете иметь специальную обработку для InvalidEnumArgumentException или ArgumentException, то они не имеют преимущества перед обычным старым Исключением.

Обычно я либо бросаю исключение, либо обертываю исключение в настраиваемом исключении.

Отредактировано для добавления: В какой-то момент я помню, что руководство от Microsoft заключалось в том, что ваше приложение никогда не должно генерировать исключения для фреймов, а должно только генерировать расширения ApplicationException.

Ответ 6

Обычно я определяю свою собственную структуру исключений, сначала создавая базовое исключение:

class MyProjectNameException:Exception
{
...constructors, etc
}

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

Ответ 7

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

Это действительно хорошая практика для разработки того, какое исключение лучше всего подходит...

Я использую в основном OperationNotSupportedException

Ответ 8

Если вы найдете исключение, которое хорошо подходит, вы можете его использовать.

Если есть сомнения, просто используйте ApplicationException. Это исключение, предназначенное для кода, который не является частью стандартной библиотеки.

Если исключение не предназначено для стандартизированного использования (например, улавливание базового класса IOException, чтобы уловить любую ошибку, связанную с I/O), сообщение, которое вы помещаете в исключение, более полезно, чем тип исключение.