2010-03-25 4 views
17
// 
// 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

Как спокойно сообщать об ошибке «удобно»? Что еще не так, что маскируется этим «удобным» подходом? –

+0

@ S.Lott: «Дружественным к пользователю» я имею в виду, что пользователь прежде всего не увидит странных (для него) сообщений об исключениях, а во-вторых позволит продолжить выполнение (даже неполное) действие, вместо сбоя приложения или что-то похожее, если исключения неправильно обрабатываются. – serhio

+3

Исключения должны быть * исключительными *. Означает ли это исключение? Я не могу сказать, не зная больше о вашей ситуации. – Thomi

ответ

7

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

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

33

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

+6

+1: Как «дружелюбно» притворяться, что ошибка не существует? –

+3

Это зависит от инвариантов каждой функции. Is * null * действительное значение? Является ли аргумент опционным? Если это ошибка в приложении, то прерывание должно быть способом, если это редкое исключительное условие, то бросание является подходящим. Иначе, если параметр является необязательным, то игнорирование его является подходящим. –

+0

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

0

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

+2

Итак, вместо того, чтобы загромождать ваш код исключениями, позволяет загромождать их ненужными абстракциями? Ошибки - это ошибки, если у вас есть четко определенный набор входов, а кто-то нарушает этот контракт ... его время бросать. – Nix

+0

@Nix Если это ошибка, но много раз это не так. –

3

Бросок.

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

0

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

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

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

1

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

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

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

0

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

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

1

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

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

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

1

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

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

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

+0

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

+0

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

+0

Я отредактировал свое сообщение, чтобы уточнить, что я имел в виду под «фатальной ошибкой». – vava

4

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

Существует третий вариант, вы можете рассмотреть следующие вопросы:

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

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

+0

обратите внимание, что вместо ArgumentNullException ("obj") вы можете написать 'ArgumentNullException (« Невозможно напечатать нулевой объект »)', чтобы быть более явным. – serhio

0

Id пойти на

недействительного PrintType (объект OBJ) { еЫпа (obj.GetType() Имя.); }

+0

Это был пример. Вместо ArgumentNullException («obj») вы можете написать 'ArgumentNullException (« Невозможно напечатать нулевой объект »)', чтобы быть более явным. – serhio

0

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

// 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

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

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

+0

при разработке вашей функции вы не можете быть уверены, что пользователь будет или не будет проверять объект. Это правда, однако, что иногда такие проверки выполняются в цепочке, если obj! Null/if obj! Null/if obj! Null/if obj! Null ... – serhio

1

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

Смежные вопросы