У меня такой код:
if (a() && b != null) {
b.doSomething();
}
Мне нужен побочный эффект a()
, даже если b
- null
. Гарантируется ли это С#? Или С# может опускать вызов a()
, если b
есть null
?
У меня такой код:
if (a() && b != null) {
b.doSomething();
}
Мне нужен побочный эффект a()
, даже если b
- null
. Гарантируется ли это С#? Или С# может опускать вызов a()
, если b
есть null
?
Да, a()
всегда будет оцениваться.
Поскольку условие оценивается слева направо, a()
всегда будет оцениваться, но b != null
будет оцениваться только в том случае, если a()
возвращает true
.
Здесь приведена точная спецификация для вас, с помощью спецификации языка С# версии 3.0. Мои акценты и решения.
7.11.1 Логические условные логические операторы
Когда операнды
&&
или||
имеют типbool
[...], операция обрабатывается следующим образом:
- Операция
x && y
оценивается какx ? y : false
. Другими словами,x
сначала оценивается и преобразуется в тип bool. Затем , еслиx
истинно, y равно оценивается и преобразуется в тип bool, и это становится результатом операция. В противном случае результат операции будет ложным.
Да, выражения оцениваются слева направо; поэтому a()
всегда будет вызываться.
См. спецификацию языка С# (ECMA 334, пункт 8.5):
За исключением операторов присваивания, все бинарные операторы лево-ассоциативный, что означает, что операции выполняются слева направо правильно. Например, x + y + z оценивается как (x + y) + z.
Условие оценивается слева направо. Таким образом, a()
всегда выполняется, но b
может не оцениваться в зависимости от результата от a()
.
a()
всегда будет оцениваться. b != null
будет оцениваться только в том случае, если a()
имеет значение true.
Это называется оценка короткого замыкания.
Левая сторона && всегда оценивается. Право будет оцениваться только в том случае, если левое значение истинно. Так что вы должны быть в порядке.
Согласно MSDN:
Операция
x && y соответствует операции
x и y, за исключением того, что если x является ложным, y не оценивается, поскольку результат операции И является ложным независимо от значения y. Это называется оценкой "короткого замыкания".
Логическое условие в вашем операторе if состоит из двух логических операторов: a()
, который всегда оценивается.
a() всегда вызывается, так как это первое, что нужно проверить в инструкции if, даже если b равно null.
Булевы выражения могут быть полностью оценены или частично, если компилятор сообщает, что дальнейшая оценка не изменит результат.
if (a() || b()) c();
Если вы полагаетесь на побочные эффекты b(), вы не получаете то, что хотите, если конкретная реализация компилятора выполняет интеллектуальную логическую оценку. Я не уверен, что в стандарте говорится об оценке булевых выражений, но если вы хотите читать читабельность вашего исходного кода, лучше всего сформулируйте его в полном объеме. Это повысит читаемость.
if (a())
{
b();
c();
}
else
if (b()) c();
Так как условия оцениваются слева направо, a()
всегда будет оцениваться. И так как вы использовали короткое замыкание AND (& &), если a()
возвращает значение false, b != null
не будет оцениваться. Если вы хотите, чтобы оба условия были оценены, возвращается ли a()
true или false, используйте оператор &
.
В дополнение к лучшему ответу:
оценка (x && y)
:
если x оценивается как false, y не будет оцениваться.
оценка (x || y)
:
если x оценивается как true, y не будет оцениваться.
В любом случае первый операнд всегда оценивается. Вы должны быть очень осторожны, чтобы иметь побочные эффекты во втором операнде.
Да, но "Не важно, что ваш код работает. Важно, чтобы ваш код был понятен" .
Я предпочитаю делать вот так:
bool val = a();
if (val && b != null) {
b.doSomething();
}
Это зависит от приоритета требуемой операции. Да, это оценивается слева направо, что означает, что() всегда выполняется перед остальными. Если вы хотите, чтобы значение b!= Null всегда оценивалось, обменивайте свою позицию.
& & условие выполняется, когда оба условия истинны.
Таким образом, функция a() выполняет, когда b не равно null.
это базовое для всех pro