Булево или содержащее троичную условную операцию не закорачивается

В общем, короткое замыкание or оператор || игнорирует правую часть или, если левая сторона оценивается как true. Видимо, мы нашли исключение из этого.

Проверьте следующее:

if (foo == null || bar != true ? foo.Count == 0 : true)
{

}

Этот код генерирует исключение нулевой ссылки на команду foo.Count так как foo нулевой. И, естественно, логическая логика учитывает это. Но если foo является нулевым, вы ожидаете, что or приведет к короткому замыканию и даже не оценит правую часть выражения, но это все равно произойдет, и оно выдаст исключение.

Это ошибка в моем коде или в компиляторе C#? Есть ли часть спецификации C#, которая обрабатывает этот случай?

4 ответа

Это потому, что ваше заявление оценивается не так, как вы ожидаете.

Вам нужна дополнительная скобка:

if(foo == null || (bar != true ? foo.Count == 0 : true))

Способ написания теперь эквивалентен (из-за приоритета оператора):

if((foo == null || bar != true) ? foo.Count == 0 : true)    

Нет, работает правильно, обратитесь к приоритету оператора. || будет оцениваться раньше ?:

Так что в первую очередь оценивает foo == null || bar != true а потом ? foo.Count == 0 : trueтак что это больше похоже на:

if ((foo == null || bar != true) ? foo.Count == 0 : true)
{

}

Если вы хотите использовать здесь короткое замыкание, то оно должно быть:

if (foo == null || (bar != true ? foo.Count == 0 : true))
{

}

Представьте скобки вокруг проверяемого условия:

if ((foo == null || bar != true) ? foo.Count == 0 : true)
{

}

Таким образом, если foo является nullты пытаешься читать foo.Countчто, естественно, приведет к NullReferenceException,

В соответствии с приоритетом оператора и ассоциативности условного оператора ?: имеет самый низкий приоритет. Таким образом это будет выполнено последним. Как это:

(foo == null || bar != true) ? foo.Count == 0 : true
Другие вопросы по тегам