Замена с нулевым распространением для проверки нуля перед условным оператором

Увидев похожий вопрос, мне было интересно, если следующее выражение...

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 доступен из другого потока (либо потому, что это поле доступно, либо потому, что оно закрыто в лямбде, который открыт другому потоку), то значение может отличаться при каждом вычислении, поэтому два фрагмента отличаются по той же причине, описанной в предыдущий абзац.

Другие вопросы по тегам