Бросить или не бросить

//
// To Throw
void PrintType(object obj)
{
    if(obj == null) 
    {
        throw new ArgumentNullException("obj")
    }
    Console.WriteLine(obj.GetType().Name);    
}

//
// Not to Throw
void PrintType(object obj)
{
    if(obj != null)
    {
        Console.WriteLine(obj.GetType().Name);
    }
}

Какой принцип сохранить?

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

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

Что Вы думаете?

17
задан serhio 25 March 2010 в 12:31
поделиться

14 ответов

Если тело метода правильно обрабатывает нулевой объект obj (другими словами, obj! = Null не является обязательным), тогда нет необходимости создавать исключение.

Во всех остальных случаях: бросить. Позвольте клиенту взять на себя ответственность за свои ошибочные данные.

7
ответ дан 30 November 2019 в 10:39
поделиться

Это действительно зависит от ваших инвариантов. Если параметр optiona, то игнорирование параметра null вполне нормально, но если параметр является обязательным, то это скроет ошибку в вашем приложении. Кроме того, в зависимости от языка, если инвариант достаточно плох, вы можете рассмотреть третий вариант: прервать приложение.

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

0
ответ дан 30 November 2019 в 10:39
поделиться

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

33
ответ дан 30 November 2019 в 10:39
поделиться

Бросок.

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

3
ответ дан 30 November 2019 в 10:39
поделиться

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

log.debug("id of object is " + obj.getId())

, где регистратор выключен, а obj имеет значение null.

1
ответ дан 30 November 2019 в 10:39
поделиться

Подумайте об использовании шаблона Нулевой объект , который очень полезен, чтобы не загромождать ваш код попытками отлова, нулевыми проверками (или не дай бог проглотить) ошибки).

0
ответ дан 30 November 2019 в 10:39
поделиться

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

1
ответ дан 30 November 2019 в 10:39
поделиться

Третий вариант, половина в псевдокоде:

// To Throw A Clean Error
void PrintType(object obj)
{
    if(obj == null) 
    {
        throw new ArgumentNullException(STANDARD_ERROR_MESSAGE, obj)
    }

    Console.WriteLine(obj.GetType().Name);    
}

Либо перехватить все ошибки и объединить их в одном месте, чтобы пользователь увидел стандартный текст:

Произошла ошибка. Если эта ошибка повторится, обратитесь к администратору .

Или выдать несколько избранных ошибок, каждая из которых удобна для пользователя, и отобразить их непосредственно пользователю. «Произошла ошибка подключения». «Произошла ошибка аутентификации». «Произошла системная ошибка». И так далее.

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

0
ответ дан 30 November 2019 в 10:39
поделиться

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

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

0
ответ дан 30 November 2019 в 10:39
поделиться

Выброс исключения (если null является ошибкой) кажется намного лучше, чем молчаливое игнорирование ошибки.

Есть и третий вариант, который можно рассмотреть:

void PrintType(object obj)
{
    Console.WriteLine(obj.GetType().Name);
}

Он также выбрасывает исключение, если obj равен null. Преимуществом этого варианта является меньший объем кода. Недостатком этого подхода является то, что сложнее определить, может ли obj быть null.

4
ответ дан 30 November 2019 в 10:39
поделиться

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

Обратите внимание: когда я говорю "фатальный", это фактически зависит от самой функции. Скажем, есть функция API, которая получает идентификатор и несколько других параметров. Предположим, что этот идентификатор также можно угадать из других переданных данных. Функция API должна угадать его, если это возможно, но функция где-то внутри, которая выполняет всю работу, должна получить идентификатор, отличный от NULL, и выбросить в противном случае. Поскольку для функции API высокого уровня это не фатально, он знает, как это угадать, но для функции низкого уровня это фатально, он должен что-то делать с этим идентификатором, а с нулевым значением он не может продолжаться.

Конечно, следует отметить все фатальные ошибки.

1
ответ дан 30 November 2019 в 10:39
поделиться

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

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

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

1
ответ дан 30 November 2019 в 10:39
поделиться

Идентификатор

void PrintType (object obj) {{{1} } Console.WriteLine (obj.GetType (). Имя); }

0
ответ дан 30 November 2019 в 10:39
поделиться

В этом конкретном примере ничего не отдавать принтеру - это все равно, что сказать «ничего не печатать», тем самым работая должным образом.

Я знаю, что это пример, но я хочу пояснить, что это относительно.

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

0
ответ дан 30 November 2019 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: