Ответ 1
Спецификация С# гарантирует, что обе стороны оцениваются ровно один раз слева направо и что не происходит короткого замыкания.
5.3.3.21 Общие правила для выражений со встроенными выражениями
К этим типам выражений применяются следующие правила: выраженные в скобках выражения (§7.6.3), выражения доступа к элементу (§7.6.6), выражения базового доступа с индексацией (§7.6.8), выражения приращения и уменьшения (§ 7.6.9, §7.7.5), литые выражения (§7.7.6), унарные +, -, ~, * выражения, двоичные +, -, *,/,%, <, → , <, < =, > , > =, ==,! =, is, as, &, |, ^ выражения (§7.8, §7.9, §7.10, §7.11), выражения составного присваивания (§7.17.2), отмеченные и непроверенные выражения (§7.6.12), плюс выражения создания массива и делегата (§7.6.10).
Каждое из этих выражений имеет одно или несколько подвыражений, которые безоговорочно оценены в фиксированном порядке.
Спецификация С# для составных операторов говорит:
7.17.2 Составное назначение
...
Операция формы
x op= y
обрабатывается путем применения разрешения перегрузки бинарных операторов (§7.3.4), как если бы операция была написанаx op y
. Тогда,
Если тип возврата выбранного оператора неявно конвертируется в тип
x
, операция оценивается какx = x op y
, за исключением того, чтоx
оценивается только один раз.В противном случае, если выбранный оператор является предопределенным оператором, если тип возврата выбранного оператора явно конвертируется в тип
x
, а еслиy
неявно конвертируется в типx
или оператор является оператором сдвига, то операция оценивается какx = (T)(x op y)
, где T является типомx
, за исключением того, чтоx
оценивается только один раз....
В вашем случае op
есть &
или |
. Короткое замыкающее поведение зеркалирует поведение &
/|
, а не &&
/||
.
Обратите внимание, что это относится только к поведению, видимому в однопоточном сценарии. Поэтому, если правая сторона не имеет побочных эффектов, которые наблюдаются в таком сценарии, компилятор или JITter по-прежнему могут опустить оценку.
В вашем примере компилятор может завершить цикл, как только он знает результат, так как таких побочных эффектов нет. Но этого не требуется.
В частности, время не считается таким побочным эффектом, и поэтому вы не можете полагаться на свой код с постоянным временем выполнения. Это может быть проблематично в контексте безопасности, поскольку оно может вводить временный боковой канал.