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

Попробовать Catch или If?

если вы считаете, что есть возможность получить исключение с нулевым указателем, следует ли использовать оператор if, чтобы убедиться, что переменная не является нулевой или вам нужно просто исключить исключение?

Я не вижу никакой разницы, так как вы можете поместить свою логику в обращение с нулевым указателем в инструкции if или в блоке catch, и какой из них лучше всего подходит?

4b9b3361

Ответ 1

Я бы сказал, что ALWAYS использует логику, чтобы поймать исключение, а не try/catch.

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

Ответ 2

Нет единого ответа, которого будет достаточно, это зависит.

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

Сценарий: метод, который принимает параметр ссылочного типа, который не принимает null

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

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

Это исключение, а именно ArgumentNullException.

Пример:

public void Write(Stream stream)
{
    if (stream == null)
        throw new ArgumentNullException("stream");
    ...

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

Q. Почему я не могу вернуть false вместо исключения исключения?

а. Поскольку возвращаемое значение легко игнорировать, вы действительно хотите, чтобы ваши методы "Write" просто молча пропускали запись, потому что вы сделали snafu в вызывающем коде, передав неправильный объект потока или что-то, что не может быть записано? Я бы не стал!

Сценарий: метод возвращает ссылку на объект, иногда нет объекта

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

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

Обобщение

Если вы внимательно рассмотрите два вышеперечисленных сценария, вы заметите одну вещь:

В обоих случаях это сводится к ожидаемому, что такое контракт.

Если в контракте указано "не null", выбросьте исключение. Не возвращайтесь к API-интерфейсу старого стиля API false, потому что исключительную проблему не следует игнорировать и игнорировать код с помощью операторов if, чтобы гарантировать, что любой вызов метода не делает для читаемого кода.

Если в контракте указано, что "null вполне возможно", обрабатывайте его с помощью операторов if.

Реклама

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

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

public void Write([NotNull] Stream stream)

[CanBeNull]
public SomeObject GetSomeObject()

Чтобы узнать больше о атрибутах контракта, используемых ReSharper, см.

Ответ 3

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

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

Я написал серию сообщений об исключениях: http://blog.gauffin.org/2013/04/what-is-exceptions/

Ответ 4

С точки зрения производительности это действительно зависит от того, что вы делаете. Влияние производительности блока try/catch, когда исключение не выбрано, минимально (и если вам действительно нужны последние несколько процентов производительности, вы, вероятно, должны переписать эту часть своего кода на С++). Бросание исключений оказывает существенное влияние на более простые операции, такие как манипуляция строками; но как только вы получаете операции с файлами/базами данных в цикле, они настолько медленнее, что снова становится тривиальным штрафом. Бросание через домен приложения будет иметь нетривиальное воздействие на что угодно, хотя.

Производительность в операциях/секунда:

Mode/operation               Empty   String      File   Database    Complex
No exception            17,748,206  267,300     2,461   877         239
Catch without exception 15,415,757  261,456     2,476   871         236
Throw                      103,456   68,952     2,236   864         236
Rethrow original            53,481   41,889     2,324   852         230
Throw across AppDomain       3,073    2,942       930   574         160

Дополнительные результаты тестирования вместе с источником для тестов можно найти в статье Последствия использования исключений в .NET

Ответ 5

Я предпочел бы, чтобы вы использовали исключение if-statement для NullReference. Для другого исключения try-catch должен быть достаточно хорошим.

Причина, по которой я предлагаю if-statement для исключения NullReference, заключается в том, что С# не укажет, какая переменная имеет значение null. если эта строка имеет более одного объекта, может быть нулевой, вы потеряете трек. Если вы используете if-statement, у вас может быть лучшее ведение журнала, чтобы помочь вам получить достаточно информации.

Ответ 6

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

Кен имеет хороший ответ:

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

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

См. эту дискуссию в этой проблеме:

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

Пустой объект означает, что данные были возвращены, а возврат null ясно указывает, что ничего не было возвращено.

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

Дальнейшее чтение:

Ответ 7

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

string name = null;

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

try
{
Console.writeLine("Name ={0}",name);
}
catch (NullRefranceException nex)
{
//handle the error 
}
catch(Exception ex)
{
 // handle error to prevent application being crashed. 
}

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

if(name !=null)
    Console.writeLine("Name ={0}",name);

Ответ 8

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

Там также вопрос оптимизации - код в try-catch блоки не будет оптимизирован.

Ответ 9

В целом, блоки try-catch великолепны, потому что они будут разбиваться (переходить в оператор catch) всякий раз, когда возникает исключение. Блоки if-else полагаются на то, что вы прогнозируете, когда произойдет ошибка.

Кроме того, блоки catch не будут останавливать ваш код от остановки при ошибке.

Ответ 10

Всегда лучше использовать Try Catch, кроме , если else Здесь Исключения - это два типа: обработано и исключенные из системы исключения Даже если вы хотите обрабатывать некоторую функцию, когда Exception u может справиться с ней...

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