Булево или содержащее троичную условную операцию не закорачивается
В общем, короткое замыкание 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