Вычисление выражения слева направо
Вопрос
В C # гарантируется ли, что выражения вычисляются слева направо?
Например:
myClass = GetClass();
if (myClass == null || myClass.Property > 0)
continue;
Существуют ли какие-либо языки, которые не соответствуют требованиям?
Решение
На самом деле вы ссылаетесь на языковую функцию под названием "короткое замыкание логических выражений".:
Что это означает, вот что:Когда результат логического выражения больше не может измениться, напримеркогда становится ясно, что выражение будет оцениваться как "true" или "false" независимо от чего, остальные части выражения оцениваться не будут.
Например, C #, Java или JavaScript делают это, и вы можете положиться на это на этих языках (чтобы ответить на ваш вопрос).
В вашем случае, если MyClass не равен null:
MyClass == null
принимает значение false- поскольку это выражение типа "или", вторая часть все еще может изменить результат, поэтому она вычисляется
myClass.Property > 0
определяет конечный результат
если MyClass равен null:
MyClass == null
принимает значение true- поскольку это выражение "или", не имеет значения, что за ним следует
- больше оценка не производится, конечный результат верен
Существуют языки, которые не замыкают логические выражения.Классический VB является примером, здесь "MyClass.Свойство > 0" будет вычислено и выдаст ошибку, если MyClass имеет значение null (в VB называется "Ничего").
Другие советы
Короткое замыкание описано в разделе 7.11 спецификации C # 3.0:
Операция x || у соответствует операция х | у, кроме того, что у оценивается, только если x не соответствует действительности.
Так что да, ты в порядке.
Что касается других языков - я никогда не люблю говорить на всех языках. В VB.NET вы можете использовать OrElse и AndAlso, которые являются короткозамкнутыми, но простыми или не являются.
Но будьте осторожны:
если у вас есть что-то вроде
sprintf (buf, "% s% s", func1 (& amp; var), func2 (& amp; var));
с побочными эффектами на var, он не определен (в C я не уверен, определен ли порядок оценки на других языках), в каком порядке выполняются func1 () и func2 () (зависит от того, в каком порядке (слева или справа) аргументы помещаются в стек и оцениваются оттуда.
Порядок оценки зависит от оператора, в данном случае от логического или ( ||
) определяется как то, что обычно называют короткое замыкание , чтобы создавать конструкции, подобные этой.
Операторы и / или в таких языках, как Ada, Visual Basic и Pascal, не закорачиваются. Они предоставляют дополнительные операторы для обеспечения этой функциональности, такие как "а затем" и "или еще" в Аде.
Я не уверен, вы действительно заинтересованы в заказе или в оценке короткого замыкания?
Я не уверен на 100%, но насколько я знаю, порядок оценки всегда будет одинаковым в C # (и я предполагаю, что большинство, если не все языки .net). Оценка короткого замыкания работает, как объяснено в предыдущих ответах.
Однако в C # вы можете отказаться от короткого замыкания, используя простые операторы (& amp; вместо & amp; & amp;). Обычно вы хотите короткого замыкания, но это может быть случай, когда вы хотите выполнить все оценки. Р>
В Python есть операторы короткого замыкания или
и и
.
В Java и Haskell & amp; & amp; и || короткое замыкание.
Интересно, что в Haskell это естественно происходит с языком (вы можете определить свои собственные операторы, которые это делают), тогда как в Java и C # это специфично для этих двух операторов.
На самом деле короткое замыкание является частью, но вам также необходимо знать, гарантирует ли язык их оценку слева направо. Например, C (ANSI, ISO, C99) НЕ гарантирует оценку слева направо. В примере кода было бы возможно проверить значение свойства перед проверкой на NULL или выполнить оба одновременно ... большинство компиляторов не делают этого, но ничто не мешает ему сделать это и полностью соответствовать спецификации. Это даже говорит вам НЕ писать такой код из-за этого.