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

//
// 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);
    }
}

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

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

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

Как вы думаете?

Ответы

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

Throw.

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

Ответ 5

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

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

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

Ответ 6

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

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

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

Ответ 7

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

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

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

Ответ 8

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

Ответ 9

С помощью Null Object pattern очень полезно не загромождать ваш код с помощью try-catch, null check (или не дай бог усвоить ошибки).

Ответ 10

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

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

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

Ответ 11

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

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

Ответ 12

Id для

void PrintType (объект obj) {   Console.WriteLine(obj.GetType() Имя.); }

Ответ 13

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

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

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

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

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

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

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

Ответ 14

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

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