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

Есть ли причина бросать исключение DivideByZeroException?

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

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

Например:

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

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

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

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

ТОЛЬКО ДЛЯ РЕЙТЕРАЦИИ:

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

4b9b3361

Ответ 1

Скажем, вы пишете библиотеку для работы с действительно большими целыми числами, которые не вписываются в Int64, тогда вам может понадобиться бросить DivideByZeroException для алгоритма деления, который вы пишете.

Ответ 2

Время выполнения .NET уже очень хорошо бросает эти исключения. Они также очень хорошо описывают, что не так, вы не можете добавить хороший комментарий к сообщению об исключении. "Вы не можете делить на ноль" не добавляет значения.

Однако вы можете избежать многих из этих исключений, просмотрев значения, переданные кодом клиента. Вам понадобится аргумент ArgumentNullException с именем аргумента, если код клиента передал значение null, исключение ArgumentException, когда оно передало что-то, что может привести к отключению DivideByZero.

Ответ 3

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

Если вы пишете библиотеку maths и имеете функцию с именем Divide(int a, int b), которая делит их, если кто-то хочет использовать ваш метод и проходит в ноль, вы захотите выбросить исключение, чтобы они, как разработчик, знайте, что они прищурились.

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

Ответ 4

Вы должны использовать исключение только для обработки Исключительных случаев.

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

Пока вы правильно обрабатываете ввод, не должно быть причин для DivideByZeroException. Если вы получили DivideByZeroException даже после проверки ввода... тогда вы знаете, что у вас есть реальная проблема (в этом случае исключение является подходящим).

Ответ 5

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

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

Ответ 6

Если вы пишете библиотеку BigInteger, вы должны обязательно добавить соответствующее исключение DivideByZero. Если вы пишете библиотеку корзины покупок, тогда... ну, возможно, нет.

Я не могу на данный момент подумать о хорошей причине бросить NullReferenceException. Если вы создаете API с документацией, в которой говорится: "Первый параметр HummingBirdFeeder.OpenSugarWaterDispenser(Dispenser dispenser, int flowRate) - это раздатчик сахарной воды, который вы хотите открыть". И если кто-то тогда придет и передаст нулевое значение этому методу, тогда вы должны обязательно выбросить ArgumentNullException.

Отказ NullReferenceException от вашего API будет просто ленив, хотя, потому что это неправильно, и это утечка некоторых из ваших внутренних компонентов.

ИЗМЕНИТЬ ДОБАВИТЬ:

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

  • Вы пишете открытый метод.
  • Получение нулевого значения для аргумента является некорректным (т.е. метод не имеет смысла без этого конкретного аргумента).
  • Документация для метода указывает, что пустые значения не разрешены.

В этом случае самое первое, что должен сделать ваш метод, это проверить нулевое значение и выставить исключение, если это условие нарушено.

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

Debug.Assert(dispenser != null);

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

Ответ 7

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

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

Krzysztof Cwalina, Проектирование многоразовых рамок

Ответ 8

Слегка вводящий в заблуждение заголовок здесь, это не о том, чтобы выбрасывать (специальное) исключение DivideByZeroException, а скорее вопрос:

Следует ли использовать исключения при проверке ввода пользователя?

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

Однако при проверке "данных" в более глубоких слоях приложения обычно нужно делать исключение.

Ответ 9

Если вы пишете числовой класс какой-либо формы и можете ожидать, что код, вызывающий ваш класс, выполнил проверку, тогда я вижу, что было бы полезно бросить исключение DivisionByZeroException, но почти в любом другом случае лучше проверить операции и выброса, а также исключение ArgumentException или ArgumentOutOfRange.

NullReferenceException - одно из зарезервированных исключений, которое использует инфраструктура, которую вы никогда не должны запускать через открытый API, наряду с IndexOutOfRange, AccessViolationException и OutOfMemoryException. См. Книгу "Рекомендации по дизайну Framework" или "Предупреждение об анализе кода"

Ответ 10

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

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

Ответ 11

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

Ответ 12

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

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

Ответ 13

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

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

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

Ответ 14

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

Ответ 15

Если вы полагаетесь на фреймворк для выполнения работы (.NET или иначе), вы должны позволить фреймворку исключать исключение.

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

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

Ответ 16

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