Надежно ли полагаться на && короткое замыкание в .NET? - PullRequest
48 голосов
/ 27 января 2011

Предположим, что myObj имеет значение null.Это безопасно написать это?

if(myObj != null && myObj.SomeString != null)

Я знаю, что некоторые языки не будут выполнять второе выражение, потому что && имеет значение false до выполнения второй части.

Ответы [ 9 ]

75 голосов
/ 27 января 2011

Да.В C # && и || имеют короткое замыкание и, таким образом, оценивают правую сторону только в том случае, если левая сторона еще не определяет результат.Операторы & и |, с другой стороны, не закорачивают и всегда оценивают обе стороны.

В спецификации сказано:

&& и || операторы называются условными логическими операторами.Их также называют «короткозамкнутыми» логическими операторами.
...
Операция x && y соответствует операции x & y, за исключением того, что y оценивается, только если x равно true
...
Операция x && y оценивается как (bool)x ? (bool)y : false.Другими словами, x сначала оценивается и преобразуется в тип bool.Затем, если x равно true, y вычисляется и преобразуется в тип bool, и это становится результатом операции.В противном случае результат операции будет false.

(Спецификация языка C # версия 4.0 - 7.12 Условные логические операторы)

Одно интересное свойство && и || в том, что они имеют короткое замыкание, даже если они не работают с bools, но это типы, где пользователь перегружал операторы & или | вместе с оператором true и false.

Операция x && y оценивается как T.false((T)x) ? (T)x : T.&((T)x, y), где T.false((T)x) - это вызов operator false, объявленный в T, а T.&((T)x, y) - это вызоввыбрано operator &.Кроме того, значение (T) x должно оцениваться только один раз.

Другими словами, x сначала оценивается и преобразуется в тип T, и в результате вызывается operator false, чтобы определить,x определенно false.
Тогда, если x определенно false, результатом операции будет значение, предварительно вычисленное для x, преобразованное в тип T.
В противном случае,y вычисляется, и выбранный оператор & вызывается для значения, ранее вычисленного для x, преобразованного в тип T, и для значения, вычисленного для y, для получения результата операции.

(Спецификация языка C # версия 4.0 - 7.12.2 Пользовательские условные логические операторы)

14 голосов
/ 27 января 2011

Да, C # использует логическое короткое замыкание.

Обратите внимание, что, хотя C # (и некоторые другие языки .NET) ведут себя таким образом, это свойство языка, а не CLR.

7 голосов
/ 22 января 2016

Я знаю, что опаздываю на вечеринку, но в C # 6.0 вы тоже можете это сделать:

if(myObj?.SomeString != null)

Что является тем же, что и выше.1006 * Что означает знак вопроса и точка оператора?значит в C # 6.0?

4 голосов
/ 27 января 2011

Ваш код в безопасности - && и || оба короткозамкнуты. Вы можете использовать не замкнутые операторы & или |, которые оценивают оба конца, но я действительно не вижу этого в большом производственном коде.

3 голосов
/ 27 января 2011

конечно, это безопасно на C #, если первый операнд имеет значение false, тогда второй никогда не вычисляется.

1 голос
/ 27 января 2011

пример

if(strString != null && strString.Length > 0)

Эта строка вызовет нулевое исключение, если обе стороны будут выполнены.

Интересное примечание. Приведенный выше пример работает немного быстрее, чем метод IsNullorEmpty.

0 голосов
/ 11 октября 2017

В C # && и || закорочены, что означает, что первое условие оценивается, а остальное игнорируется, если определен ответ.

В VB.NET AndAlso и OrElse также закорочены.

В javaScript && и || также закорочены.

Я упоминаю VB.NET, чтобы показать, что у безобразного рыжего пасынка .net тоже иногда есть классные вещи.

Я упоминаю javaScript, потому что, если вы занимаетесь веб-разработкой, вы, вероятно, также можете использовать javaScript.

0 голосов
/ 27 января 2011

Да, C # и большинство языков вычисляют предложения if слева направо.

VB6, кстати, вычислит все это и сгенерирует исключение, если оно нулевое ...

0 голосов
/ 27 января 2011

Это совершенно безопасно. C # является одним из этих языков.

...