//
// 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);
}
}
Какой принцип сохранить?
Лично я предпочитаю первый говорить благоприятный для разработчика (уведомленный о каждой "аномалии"). Второй говорить удобный для пользователя (позволяют пользователю продолжить работу, даже если "внутри" не все делает правильно).
Я думаю, что это более сложно для нахождения ошибок и ошибок в этап технического обслуживания при тихом разрешении вещам продолжиться. Если что-то идет не так, как надо, Вы не уведомляетесь сразу, и иногда имеете ошибки далеко от основной ошибочной причины и проводите много времени для нахождения его.
Что Вы думаете?
Если тело метода правильно обрабатывает нулевой объект obj (другими словами, obj! = Null не является обязательным), тогда нет необходимости создавать исключение.
Во всех остальных случаях: бросить. Позвольте клиенту взять на себя ответственность за свои ошибочные данные.
Это действительно зависит от ваших инвариантов. Если параметр optiona, то игнорирование параметра null вполне нормально, но если параметр является обязательным, то это скроет ошибку в вашем приложении. Кроме того, в зависимости от языка, если инвариант достаточно плох, вы можете рассмотреть третий вариант: прервать приложение.
Все дискуссии о том, следует ли использовать исключения или нет, всегда можно связать с решением о том, является ли ситуация исключительной или нет, и, если она является исключительной, бросание или, скорее, прерывание приложения зависит от того, является ли оно исключительным или нет. можно восстановить или нет.
Второй смертельный. Тихая неудача - это всегда неправильный поступок. Предположим, это была банковская система в банке, в котором открыт ваш счет. Хотели бы вы, если бы возникла проблема с выплатой вашей зарплаты, а система молча ее проигнорировала?
Бросок.
Позвольте вызывающему объекту функции определить, достаточно ли важно выдать пользователю исключение для нулевого значения, но сама функция должна выдать ошибку из-за недопустимого аргумента.
Всегда Выбрасывать, кроме в коде отладки / диагностики. Очень неприятно иметь исключение NullPointerException, которое возникает в производственном коде в точке, где должно быть сгенерировано только отладочное сообщение, например
log.debug("id of object is " + obj.getId())
, где регистратор выключен, а obj имеет значение null.
Подумайте об использовании шаблона Нулевой объект , который очень полезен, чтобы не загромождать ваш код попытками отлова, нулевыми проверками (или не дай бог проглотить) ошибки).
Если ваш api открыт снаружи, всегда проверяйте аргументы и генерируйте исключение на основе аргументов, чтобы пользователь api мог получить результат.
Третий вариант, половина в псевдокоде:
// To Throw A Clean Error
void PrintType(object obj)
{
if(obj == null)
{
throw new ArgumentNullException(STANDARD_ERROR_MESSAGE, obj)
}
Console.WriteLine(obj.GetType().Name);
}
Либо перехватить все ошибки и объединить их в одном месте, чтобы пользователь увидел стандартный текст:
Произошла ошибка. Если эта ошибка повторится, обратитесь к администратору .
Или выдать несколько избранных ошибок, каждая из которых удобна для пользователя, и отобразить их непосредственно пользователю. «Произошла ошибка подключения». «Произошла ошибка аутентификации». «Произошла системная ошибка». И так далее.
На бэкэнде должны регистрироваться все ошибки и трассировка их стека, чтобы вы могли использовать отладочную информацию таким образом.
Это действительно зависит от того, для чего определена функция. Наиболее важным аспектом является наличие четко определенного поведения и правильная реализация функции.
Теперь, если вопрос заключается в том, что лучше - определить функцию так, чтобы она принимала null и выводила его, или не принимала его и выбрасывала исключение, я бы сказал последнее, потому что, вероятно, пользователь будет меньше подвержен ошибкам, проверяя null перед вызовом функции, если это возможно.
Выброс исключения (если null является ошибкой) кажется намного лучше, чем молчаливое игнорирование ошибки.
Есть и третий вариант, который можно рассмотреть:
void PrintType(object obj)
{
Console.WriteLine(obj.GetType().Name);
}
Он также выбрасывает исключение, если obj равен null. Преимуществом этого варианта является меньший объем кода. Недостатком этого подхода является то, что сложнее определить, может ли obj быть null.
Это очень субъективно, но я всегда предпочитаю просто игнорировать нефатальные или исправимые ошибки. Поместите их в журналы, если нужно, но если вы знаете, как продолжить - сделайте это.
Обратите внимание: когда я говорю "фатальный", это фактически зависит от самой функции. Скажем, есть функция API, которая получает идентификатор и несколько других параметров. Предположим, что этот идентификатор также можно угадать из других переданных данных. Функция API должна угадать его, если это возможно, но функция где-то внутри, которая выполняет всю работу, должна получить идентификатор, отличный от NULL, и выбросить в противном случае. Поскольку для функции API высокого уровня это не фатально, он знает, как это угадать, но для функции низкого уровня это фатально, он должен что-то делать с этим идентификатором, а с нулевым значением он не может продолжаться.
Конечно, следует отметить все фатальные ошибки.
Я бы сказал, что это зависит от ваших предпочтений (разработчика). С точки зрения пользователя он никогда не должен видеть необработанное исключение, но это не означает, что вы не можете использовать исключения.
Я предпочитаю первую, потому что считаю null
совершенно ненужной (и раздражающей) конструкцией, поэтому я стараюсь писать код без нее. Если где-то есть null
, значит, кто-то допустил ошибку, поэтому лучше всего просто выйти из системы, а не делать вид, что все в порядке.
В конце концов, это зависит от того, что вы считаете семантикой метода. Если предполагается, что метод принимает значения NULL, вам следует выбрать вариант номер два. Если предполагается, что метод принимает только реальные аргументы (что я предпочитаю), вам следует выбрать вариант номер один.
Идентификатор
void PrintType (object obj) {{{1} } Console.WriteLine (obj.GetType (). Имя); }
В этом конкретном примере ничего не отдавать принтеру - это все равно, что сказать «ничего не печатать», тем самым работая должным образом.
Я знаю, что это пример, но я хочу пояснить, что это относительно.
Если ваш код каким-то образом отображает понятные сообщения об исключениях, какая разница? первый будет удобен как для разработчиков, так и для пользователей.