Полагается на & & короткое замыкание безопасно in.NET?


Предположим, что myObj равно нулю. Безопасно ли это писать?

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

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

9 41

9 ответов:

Да. В 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 определяемые пользователем условные логические операторы)

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

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

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

if(myObj?.SomeString != null)

Это то же самое, что и выше.

Также см.: что означает оператор вопросительного знака и точки ?. значит, в C# 6.0?

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

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

Примером может служить

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

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

Интересная заметка. Приведенный выше пример является довольно быстрым, чем метод IsNullorEmpty.

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

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

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

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

В VB.NET, AndAlso и OrElse также являются короткозамкнутыми.

В javaScript && и || также являются короткозамкнутыми.

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

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