Как выбрать наиболее подходящий тип исключения для броска? - PullRequest
21 голосов
/ 27 мая 2009

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

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

    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, вероятно, было бы более уместным, если бы я знал о его существовании в то время.

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

Редактировать

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

Ответы [ 8 ]

12 голосов
/ 27 мая 2009

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

PS Рассмотрим подписку на его блог. Хорошего чтения!

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

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

9 голосов
/ 27 мая 2009

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

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

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

Редактировать: Если вам нужно краткое руководство по наиболее распространенным, см. Страницу Общие исключения () в MSDN.

4 голосов
/ 27 мая 2009

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

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

3 голосов
/ 27 мая 2009

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

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

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

2 голосов
/ 27 мая 2009

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

Обычно я выбрасываю исключение или заключаю исключение в пользовательское исключение.

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

1 голос
/ 27 мая 2009

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

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

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

1 голос
/ 27 мая 2009

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

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

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

1 голос
/ 27 мая 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...