2

Посмотрев similar question, мне было интересно, если следующее выражение ...Null-распространения для проверки нулевой предварительного условного оператора

if (attribute != null && attribute.Description == input) 

... будет вести себя (почти) идентичны, к следующему нулевому распространения вариант?

if (attribute?.Description == input) 

До сих пор я мог определить только после (как-то незначительные) различия:

  • не представляется возможным в случае input имеет ненулевых типа в случае input
  • бы сам null, поведение будет изменен

Я что-то пропустил? или существуют другие отличия в поведении?


EDIT: в конце концов, только отказоустойчивая альтернатива я нашел для первого фрагмента кода, будет:

if (attribute?.Description?.Equals(input) ?? false) 
+1

'attribute' оценивается только один раз во втором случае, поэтому вы никогда не сможете получить' NullReferenceException'. В первом случае, если атрибут 'attribute' изменяется от ненулевого значения до нуля после оценки первого условия, но перед оценкой второго, вы все равно увидите исключение ... –

+0

Если вы не хотите разрешите 'input' быть' null', вы должны сначала проверить это. Тогда нет никакой разницы, потому что значение nullable можно сравнить с не-nullable. –

+0

@TimSchmelter Это на самом деле вам не поможет. Дело в том, что два фрагмента * ведут себя * по-разному, когда 'input' равно null, и они делают это таким образом, что для второго фрагмента вы не можете просто проверить его первым; вам нужно будет реорганизовать второй фрагмент в нечто похожее на первое, чтобы оно вернуло правильный результат, если 'input' разрешено быть« null ». – Servy

ответ

3

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

Единственное различие в поведении, как вы упомянули, что, если input является null, то второй фрагмент кода не имеет возможности дифференциации между attribute быть null, когда он должен быть false, и где Description является null, где он должен be true.

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

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

+0

Откуда вы знаете, что его никогда не было «нулевым»? Работа с контрактами? – Mafii

+0

В моем случае вход поступает из предопределенного файла конфигурации. –

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