Я хотел бы использовать: ArgumentException
, ArgumentNullException
, и ArgumentOutOfRangeException
.
Есть и другие варианты, которые не фокусируются так сильно на самом аргументе, а скорее оценивают вызов в целом:
InvalidOperationException
- Аргумент может быть в порядке, но не в текущем состоянии объекта. Кредит идет в STW (ранее Yoooder). Голосуйте также за его ответ .
NotSupportedException
- Переданные аргументы действительны, но просто не поддерживаются в этой реализации. Представьте себе FTP-клиент, и вы передаете команду, которую клиент не поддерживает.
Хитрость заключается в том, чтобы создать исключение, которое лучше всего объясняет, почему метод нельзя назвать таким, какой он есть. В идеале, исключение должно быть детализированным о том, что пошло не так, почему это не так и как это исправить.
Мне нравится, когда сообщения об ошибках указывают на помощь, документацию или другие ресурсы. Например, Microsoft сделала хороший первый шаг со своими статьями базы знаний, например, «Почему я получаю сообщение об ошибке« Операция прервана »при посещении веб-страницы в Internet Explorer?» , Когда вы сталкиваетесь с ошибкой, они указывают на статью базы знаний в сообщении об ошибке. Что они не делают хорошо, так это то, что они не говорят вам, почему конкретно это не удалось.
Спасибо STW (бывший Yoooder) еще раз за комментарии.
В ответ на ваше продолжение я бы кинул ArgumentOutOfRangeException
. Посмотрите, что MSDN говорит об этом исключении:
ArgumentOutOfRangeException
генерируется, когда вызывается метод, и хотя бы один из аргументов, передаваемых методу, не является пустой ссылкой ( Nothing
в Visual Basic) и не содержит допустимого значения.
Таким образом, в этом случае вы передаете значение, но это недопустимое значение, поскольку ваш диапазон составляет 1–12. Однако то, как вы документируете, проясняет, что выдает ваш API. Потому что, хотя я мог бы сказать ArgumentOutOfRangeException
, другой разработчик мог бы сказать ArgumentException
. Сделать это легко и документировать поведение.
FormatException
: Исключение, которое выдается, когда формат аргумента недопустим или когда строка составного формата не правильно сформирована.Я проголосовал за ответ Джоша , но хотел бы добавить еще один в список:
System.InvalidOperationException должно быть выброшено, если аргумент допустим, но объект находится в состоянии, где аргумент не должен использоваться.
Обновление взято из MSDN:
Допустим, у вашего объекта есть метод PerformAction (действие enmSomeAction), допустимыми являются enmSomeActions Open и Close. Если вы вызываете PerformAction (enmSomeAction.Open) два раза подряд, то второй вызов должен вызвать исключение InvalidOperationException (поскольку arugment был действителен, но не для текущего состояния элемента управления)
Поскольку вы уже делаете правильные вещи, программируя в обороне, я должен упомянуть еще одно исключение - ObjectDisposedException. Если ваш объект реализует IDisposable, то у вас всегда должна быть переменная класса, отслеживающая состояние удаления; если ваш объект был удален и для него был вызван метод, вы должны вызвать исключение ObjectDisposedException:
Обновление: чтобы ответить на ваши последующие действия: Это немного двусмысленная ситуация, и она немного усложняется из-за общего (не в смысле .NET Generics) типа данных, используемого для представления определенного набора данных; перечисление или другой строго типизированный объект были бы более идеальными, но мы не всегда имеем такой контроль.
Я лично склонялся бы к ArgumentOutOfRangeException и предоставил бы сообщение, которое указывает, что допустимые значения 1-12. Я рассуждаю так: когда вы говорите о месяцах, предполагая, что все целочисленные представления месяцев действительны, то вы ожидаете значение в диапазоне 1-12. Если бы действовали только определенные месяцы (например, месяцы, в которых было 31 день), вы бы не имели дело с самим диапазоном, и я бы выдал обобщенное исключение ArgumentException, в котором указаны действительные значения, и я также задокументировал бы их в комментариях метода.
источник
В зависимости от фактического значения и того, какое исключение подходит лучше всего:
ArgumentException
(что-то не так со значением)ArgumentNullException
(аргумент нулевой, хотя это не разрешено)ArgumentOutOfRangeException
(аргумент имеет значение вне допустимого диапазона)Если это не достаточно точно, просто выведите свой собственный класс исключений из
ArgumentException
.Ответ Yoooder просветил меня. Ввод недействителен, если он недействителен в любое время, в то время как ввод является неожиданным, если он недопустим для текущего состояния системы. Так что в последнем случае
InvalidOperationException
разумный выбор.источник
исключение аргумента.
источник
ArgumentException :
Несколько подклассов также существуют для определенных типов инвалидности. Ссылка содержит резюме подтипов и когда они должны применяться.
источник
Краткий ответ:
ни
Более длинный ответ:
использование Argument * Exception (кроме библиотеки, в которой есть продукт, например, библиотека компонентов) - это запах. Исключением является обработка исключительных ситуаций, а не ошибок и нехваток пользователя (т. Е. Пользователя API).
Самый длинный ответ:
Бросать исключения для недопустимых аргументов - это грубо, если только вы не пишете библиотеку.
Я предпочитаю использовать утверждения по двум (или более) причинам:
Вот как выглядит обработка нулевого исключения (очевидно, с сарказмом):
Исключения должны использоваться, когда ситуация ожидаема, но исключительна (случаются вещи, которые находятся вне контроля потребителя, такие как сбой ввода-вывода). Аргумент * Исключение является признаком ошибки и должно (на мой взгляд) обрабатываться с помощью тестов и помогать с Debug.Assert
Кстати: в данном конкретном случае вы могли бы использовать тип Month вместо int. C # терпит неудачу, когда дело доходит до безопасности типов (Aspect # rulez!), Но иногда вы можете предотвратить (или отловить во время компиляции) эти ошибки все вместе.
И да, MicroSoft ошибается в этом.
источник
Существует стандартное ArgumentException, которое вы можете использовать, или вы можете создать подкласс и создать свой собственный. Существует несколько конкретных классов ArgumentException:
http://msdn.microsoft.com/en-us/library/system.argumentexception(VS.71).aspx
Какой из них работает лучше всего.
источник