Есть ли какая-либо причина для создания исключения DivideByZeroException? - PullRequest
21 голосов
/ 08 апреля 2010

Есть ли случаи, когда стоит throw ошибок, которых можно избежать?

Я конкретно думаю о DivideByZeroException и ArgumentNullException

Например:

double numerator = 10;
double denominator = getDenominator();

if( denominator == 0 ){
   throw new DivideByZeroException("You can't divide by Zero!");
}

Есть ли какие-либо причины для выдачи ошибки, подобной этой?

ПРИМЕЧАНИЕ: Я не говорю о перехвате этих ошибок, но конкретно о том, чтобы знать, есть ли когда-нибудь веские причины для их выброса.

ПРОСТО ПОВТОРЯТЬ :

Я ЗНАЮ, что в приведенном мной примере вам, вероятно, будет лучше справиться с ошибкой. Возможно, вопрос следует перефразировать. Есть ли причины для throw одной из этих ошибок вместо обработки ее в этом месте.

Ответы [ 16 ]

0 голосов
/ 08 апреля 2010

Никогда (пользователь никогда не отправит 0 в качестве знаменателя) и всегда (пользователь всегда предоставит соответствующие значения аргументов) - опасные идеи для включения в ваш код. Очень маленький процент из нас программирует один код, который никогда не будет изменен или вызван другим разработчиком. Итак, нам нужно написать защитный код. В случае деления на ноль, я не должен решать, каким должен быть соответствующий результат, который возвращается к вызывающей стороне. Бросок исключения кажется разумным способом вернуть проблему обратно. Несмотря на связанные с этим расходы, любая инфраструктура, которую я добавляю в свой код, чтобы избежать создания исключения, также добавляет затраты.

0 голосов
/ 08 апреля 2010

Учтите, что для двойных значений деление на ноль фактически приведет к значению: double.Infinity, double.NegativeInfinity или double.NaN, в зависимости от того, является ли числитель положительным, отрицательным или нулевым, соответственно.

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

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

0 голосов
/ 08 апреля 2010

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

Принцип хорошего дизайна состоит в том, чтобы ваша программа распознавала и корректно обрабатывала исключительные ситуации. Кроме того, это хорошая идея предоставить своим пользователям (и в конечном итоге себе) достаточно информации для диагностики ошибок - особенно тех, которые может произойти после того, как ваш код развернут. Следовательно, иногда имеет смысл выдавать исключения, такие как вид, иллюстрирующий, если это сделает код вашего приложения более надежным и более легким для диагностики.

0 голосов
/ 08 апреля 2010

Хорошей практикой является выполнение этих проверок в верхней части функции перед началом обработки данных. Вместо этого бросая их (или любой другой метод генерирует эти исключения) в середине метода.

0 голосов
/ 08 апреля 2010

Создание исключения - дорогая вещь с точки зрения ресурса. Вы уже предотвратили возникновение исключения, так зачем его выбрасывать? Если вам нужно сообщить пользователю, используйте какой-нибудь механизм обмена сообщениями. Если вам нужно знать об этом самостоятельно, зарегистрируйтесь.

0 голосов
/ 08 апреля 2010

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

По крайней мере, так сказал мне мой старший разработчик, когда я пытался поймать DivideByZeroException много месяцев назад.

...