Оценка выражения слева направо - PullRequest
5 голосов
/ 03 декабря 2008

В C # гарантируется, что выражения вычисляются слева направо?

Например:

myClass = GetClass();  
if (myClass == null || myClass.Property > 0)  
    continue;

Есть ли языки, которые не соответствуют?

Ответы [ 9 ]

14 голосов
/ 03 декабря 2008

Вы на самом деле ссылаетесь на языковую функцию, называемую «короткое замыкание логических выражений»:

Это означает следующее: когда результат логического выражения больше не может измениться, например, когда становится ясно, что выражение будет иметь значение «истина» или «ложь», независимо от того, что, остальные части выражения не будут оцениваться.

Например, C #, Java или JavaScript делают это, и вы можете положиться на них на этих языках (чтобы ответить на ваш вопрос).

В вашем случае, если MyClass не равен нулю:

  • MyClass == null оценивается как ложное
  • , поскольку это выражение "или", вторая часть все еще может изменить результат, поэтому он оценивается
  • myClass.Property > 0 определяет конечный результат

если MyClass равен нулю:

  • MyClass == null оценивается как истинное
  • поскольку это выражение "или", не имеет значения, что следует за
  • оценка больше не производится, конечный результат верен

Есть языки, которые не замыкают логические выражения. Классический VB является примером, здесь «myClass.Property> 0» будет оценен и выдаст ошибку, если MyClass будет нулевым (в VB он называется «Nothing»).

5 голосов
/ 03 декабря 2008

Короткое замыкание описано в разделе 7.11 спецификации C # 3.0:

Операция х || у соответствует операция х | у, кроме того, что у оценивается, только если x не соответствует действительности.

Так что да, ты в порядке.

Что касается других языков - мне никогда не нравится говорить на всех языках. В VB.NET вы можете использовать OrElse и AndAlso, которые являются короткозамкнутыми, но простыми или не являются.

2 голосов
/ 03 декабря 2008

Но будьте осторожны:

если у вас есть что-то вроде

sprintf (buf, "% s% s", func1 (& var), func2 (& var));

с побочными эффектами на var, он не определен (в C я не уверен, определен ли порядок оценки на других языках), в каком порядке выполняются func1 () и func2 () (зависит, в каком порядке (влево или вправо) аргументы помещаются в стек и оцениваются оттуда.

0 голосов
/ 13 апреля 2010

На самом деле короткое замыкание является частью, но вам также необходимо знать, гарантирует ли язык их оценку слева направо. Например, C (ANSI, ISO, C99) НЕ гарантирует оценку слева направо. В примере кода было бы возможно проверить значение свойства перед проверкой на NULL или сделать оба одновременно ... большинство компиляторов не делают, но ничто не мешает ему сделать это и полностью соответствовать спецификации. Это даже говорит вам НЕ писать такой код из-за этого.

0 голосов
/ 03 декабря 2008

В Java и Haskell && и || короткое замыкание.

Интересно отметить: в Haskell это естественно происходит с языком (вы можете определить свои собственные операторы, которые делают это), тогда как в Java и C # это специфично для этих двух операторов.

0 голосов
/ 03 декабря 2008

Python имеет операторы короткого замыкания or и and.

0 голосов
/ 03 декабря 2008

Операторы и / или в таких языках, как Ada, Visual Basic и Pascal, не закорачиваются. Они предоставляют дополнительные операторы для разрешения этой функциональности, такие как «и затем» и «или еще» в Ada.

0 голосов
/ 03 декабря 2008

Я не уверен, вы действительно заинтересованы в заказе или оценке короткого замыкания?

Я не уверен на 100%, но насколько я знаю, порядок оценки всегда будет одинаковым в C # (и я предполагаю, что большинство, если не все языки .net). Оценка короткого замыкания работает, как объяснено в предыдущих ответах.

Однако в C # вы можете не замыкать накоротко, используя простые операторы (& вместо &&). Обычно вы хотите короткого замыкания, но это может быть случай, когда вы хотите выполнить все оценки.

0 голосов
/ 03 декабря 2008

Порядок вычисления зависит от оператора, в этом случае логическое значение или (<a href="http://msdn.microsoft.com/en-us/library/6373h346(VS.71).aspx" rel="nofollow noreferrer">||</a>) определяется как то, что обычно называется коротким замыканием , для создания конструкций, подобных этой работе.

...