Я хотел бы предотвратить дальнейшую обработку объекта, если он нулевой.
В следующем коде я проверяю, является ли объект нулевым, либо:
if (!data.Equals(null))
и
if (data != null)
Тем не менее, я получаю NullReferenceException
в dataList.Add(data)
. Если объект был нулевым, он никогда не должен был бы войти в if
-состояние!
Таким образом, я спрашиваю, является ли это правильным способом проверки, является ли объект нулевым:
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
// I've also used "if (data != null)" which hasn't worked either
if (!data.Equals(null))
{
//NullReferenceException occurs here ...
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
Если это правильный способ проверить, является ли объект нулевым, что я делаю неправильно (как я могу предотвратить дальнейшую обработку объекта, чтобы избежать исключения NullReferenceException)?
c#
null
nullreferenceexception
разработчик
источник
источник
throw e;
противthrow new Exception(e.ToString());
!= null
в своих нулевых проверках..Equals
всегда будет выдавать исключение, если объект нулевой.throw e;
не намного лучше.throw;
с другой стороны ...e.ToString()
создаст строку, которая включает в себя не только сообщение об ошибке, но также и всеInnerExceptions
и трассировку стека. Так что это вроде очень толстого сообщения об исключении. Если вы (правильно!) Хотите сохранить эту информацию и сохранить ее, используйте простоthrow;
.Ответы:
Это не
data
то естьnull
, ноdataList
.Вам нужно создать один с
Еще лучше: так как это поле, сделайте это
private
. И если ничто не мешает тебе, сделай это тожеreadonly
. Просто хорошая практика.В стороне
Правильный способ проверки на ничтожность
if(data != null)
. Этот вид проверки повсеместен для ссылочных типов; дажеNullable<T>
переопределяет оператор равенства, чтобы быть более удобным способом выраженияnullable.HasValue
при проверке на ничтожность.Если вы это сделаете,
if(!data.Equals(null))
то вы получите,NullReferenceException
еслиdata == null
. Что довольно смешно, потому что избегание этого исключения было целью в первую очередь.Вы также делаете это:
Это определенно не хорошо. Я могу себе представить, что вы положили его туда только для того, чтобы вы могли взломать отладчик, оставаясь внутри метода, и в этом случае пропустите этот абзац. В противном случае, не ловите исключения даром. И если вы делаете, отбросьте их, используя только
throw;
.источник
null != data
. Помещение константы первым превращает опечаткуnull = data
в ошибку компилятора, а не в непреднамеренное присваивание. (Также работает для==
.)if (data = null)
уже есть ошибка времени компиляции, так что даже если бы потребовались десятилетия, чтобы добраться до нас, нам больше не нужно следить за этим. Даже компиляторы C ++ легко выдадут предупреждение о возможном непреднамеренном назначении этого кода.в C #> 7.0 использовать
if (obj is null)
...Это будет игнорировать любые == или! = Определенные объектом (если, конечно, вы не хотите их использовать ...)
Для ненулевого использования
if (obj is object)
(илиif (!(obj is null))
)источник
obj is not null
)if (obj aint null)
:(if (obj is object)
C # 6 имеет монадическую проверку нуля :)
перед:
после:
источник
result = myObject == null ? null : myObject.SomeProperty
и ваш пример подсказал мне написатьresult = myObject?.SomeProperty
. Мужчина!! Это подлый. Я все еще люблю кодировать ...Ваш dataList является нулевым, поскольку он не был создан, судя по коду, который вы опубликовали.
Пытаться:
}
источник
[Отредактировано, чтобы отразить подсказку @ kelton52]
Самый простой способ это сделать
object.ReferenceEquals(null, data)
Поскольку
(null==data)
НЕ гарантируется работа:Производит:
источник
Нет, ты должен использовать
!=
. Если значениеdata
на самом деле равно нулю, ваша программа просто завершится с ошибкойNullReferenceException
в результате попытки вызоваEquals
методаnull
. Также поймите, что если вы специально хотите проверить равенство ссылок, вам следует использоватьObject.ReferenceEquals
метод, так как вы никогда не знаете, какEquals
он реализован.Ваша программа аварийно завершает работу, потому что
dataList
имеет значение null, поскольку вы никогда не инициализируете ее.источник
Проблема в этом случае не в том, что
data
это ноль. Это то, чтоdataList
само по себе является нулевым.В месте, где вы объявляете,
dataList
вы должны создать новыйList
объект и присвоить его переменной.источник
В дополнение к ответу @Jose Ortega , его лучше использовать метод расширения
И использовать
IsNull
метод для всех объектов, таких как:источник
return T == null ? true : false;
и не простоreturn T == null;
?Начиная с C # 8, вы можете использовать «пустой» шаблон свойства (с сопоставлением с шаблоном ), чтобы гарантировать, что объект не является нулевым:
Этот подход означает « если объект ссылается на экземпляр чего-либо » (т. Е. Он не равен нулю).
Вы можете думать об этом как противоположность:
if (obj is null)...
. который вернет true, когда объект не ссылается на экземпляр чего-либо.Подробнее о шаблонах в C # 8.0 читайте здесь .
источник
Начиная с C # 9 вы можете сделать
Для ненулевого использования
Если вам нужно переопределить это поведение, используйте
==
и!=
соответственно.источник
Джеффри Л. Уитледж прав. Ваш `dataList´-Object сам по себе равен нулю.
Есть и другая проблема с вашим кодом: вы используете ключевое слово ref, что означает, что данные аргумента не могут быть нулевыми! MSDN говорит:
Также не рекомендуется использовать дженерики с типом `Object´. Дженерики должны избегать бокса / распаковки, а также обеспечивать безопасность типов. Если вы хотите общий тип, сделайте ваш метод универсальным. Наконец ваш код должен выглядеть так:
источник
Как и другие уже указывали, это не ,
data
а скорее всего ,dataList
что этоnull
. В дополнение к этому...catch
-throw
это антипаттерн, который почти всегда вызывает у меня рвоту каждый раз, когда я это вижу. Представьте, что что-то идет не так в глубине чего-то, чтоdoOtherStuff()
вызывает. Все, что вы получите, этоException
объект, брошенныйthrow
вAddData()
. Нет трассировки стека, нет информации о вызове, нет состояния, вообще ничего не указывает на реальный источник проблемы, если только вы не включите и не переключите свой отладчик, чтобы сломать исключение, а не обработанное исключение. Если вы поймать исключение и просто повторно бросает его в любом случае , особенно если код в блоке Ьгу в любом случае нетривиально, делать себя (и своих коллег, настоящее и будущее) одолжение и выплеснуть цельныеtry
-catch
блок , Предоставляется,throw;
лучше, чем альтернативы, но вы все еще даете себе (или кому-либо еще, кто пытается исправить ошибку в коде) совершенно ненужные головные боли. Это не означает, что try-catch-throw обязательно является злом само по себе, если вы делаете что-то релевантное с объектом исключения, который был брошен внутри блока catch.Тогда есть потенциальные проблемы с ловлей
Exception
в первую очередь, но это другой вопрос, особенно потому, что в этом конкретном случае вы бросаете исключение.Еще одна вещь, которая кажется мне более чем немного опасной, это то, что она
data
может изменить значение во время выполнения функции, поскольку вы передаете по ссылке. Таким образом, нулевая проверка может пройти, но прежде чем код начнет что-либо делать со значением, он будет изменен - возможно, наnull
. Я не уверен, если это беспокойство или нет (это может быть не так), но, похоже, стоит остерегаться.источник
использовать:
Условное использование:
Обновление (другой способ) обновлено 31.08.2017. Спасибо за комментарий.
источник
cond ? true : false;
полностью эквивалентно простоcond
. Это ничего не добавляет.return T == null;
также возвращает логическое значение!return T == null ? true : false;
просто использоватьreturn T == null;
.Всякий раз, когда вы создаете объекты класса, вы должны проверить, является ли объект нулевым или нет, используя приведенный ниже код.
Пример: object1 является объектом класса
источник
Я просто следовал методу, которому мы обычно следовали в java-скрипте. Чтобы преобразовать объект в строку, а затем проверить, являются ли они нулевыми.
источник
Я сделал более простой (позитивный способ), и, кажется, работает хорошо.
Поскольку любой вид «объекта» является, по крайней мере, объектом
источник