Замена с нулевым распространением для проверки нуля перед условным оператором
Увидев похожий вопрос, мне было интересно, если следующее выражение...
if (attribute != null && attribute.Description == input)
... будет вести себя (почти) идентично следующему варианту нулевого распространения?
if (attribute?.Description == input)
До сих пор я мог определить только следующие (как-то незначительные) различия:
- невозможно в случае
input
имеет ненулевой тип - в случае
input
был бы самnull
, поведение будет изменено
Я что-то пропустил? или есть другие различия в поведении?
РЕДАКТИРОВАТЬ: в конце концов, единственная отказоустойчивая альтернатива, которую я нашел для первого фрагмента, будет:
if (attribute?.Description?.Equals(input) ?? false)
1 ответ
Код будет работать, если input
имеет ненулевой тип. Существует неявное преобразование всех необнуляемых типов в их обнуляемые аналоги, поэтому input
будет просто поднят до нуля для сравнения со значением свойства.
Как вы упомянули, единственная разница в поведении заключается в том, что если input
является null
то второй фрагмент не имеет никакого способа различить attribute
являющийся null
когда это должно быть false
, и где Description
является null
где это должно быть true
,
О, и это при условии, что attribute
является локальной переменной или полем. Если это свойство (или на самом деле является более сложным выражением), то оно может иметь побочные эффекты или приводить к другому значению при вычислении дважды, как это происходит в первом фрагменте, но не во втором, что является различием в поведении.
Все это, конечно, предполагает однопоточный контекст. В многопоточном контексте, если attribute
доступен из другого потока (либо потому, что это поле доступно, либо потому, что оно закрыто в лямбде, который открыт другому потоку), то значение может отличаться при каждом вычислении, поэтому два фрагмента отличаются по той же причине, описанной в предыдущий абзац.