Предположим, что myObj равно null. Можно ли написать это?
if(myObj != null && myObj.SomeString != null)
Я знаю, что некоторые языки не будут выполнять второе выражение, потому что && оценивает значение false до выполнения второй части.
Предположим, что myObj равно null. Можно ли написать это?
if(myObj != null && myObj.SomeString != null)
Я знаю, что некоторые языки не будут выполнять второе выражение, потому что && оценивает значение false до выполнения второй части.
Да. В С# &&
и ||
закорочены и, следовательно, оценивают правую сторону, только если левая сторона еще не определяет результат. Операторы &
и |
, с другой стороны, не замыкаются и всегда оценивают обе стороны.
Спектр говорит:
Операторы
&&
и||
называются условными логическими операторами. Их также называют логическими операторами "короткого замыкания".
...
Операцияx && y
соответствует операцииx & y
, за исключением того, чтоy
оценивается, только еслиx
-true
...
Операцияx && y
оценивается как(bool)x ? (bool)y : false
. Другими словами,x
сначала оценивается и преобразуется в типbool
. Затем, еслиx
true
,y
оценивается и преобразуется в типbool
, и это становится результатом операции. В противном случае результатом операции будетfalse
.
(Спецификация языка С# Версия 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
, чтобы получить результат операции.
(С# Language Specification Version 4.0 - 7.12.2 Пользовательские условно-логические операторы)
Да, С# использует логическое короткое замыкание.
Обратите внимание, что хотя С# (и некоторые другие языки .NET) ведут себя таким образом, это свойство языка, а не CLR.
Ваш код в безопасности - && и || оба короткозамкнуты. Вы можете использовать некороткозамкнутые операторы и /, которые оценивают оба конца, но я действительно не вижу этого в большом производственном коде.
Я знаю, что опаздываю на вечеринку, но в С# 6.0 вы тоже можете это сделать:
if(myObj?.SomeString != null)
Это то же самое, что и выше.
Также смотрите: Что делает знак вопроса и точечный оператор?. в С# 6.0?
уверен, что он безопасен на С#, если первый операнд является ложным, а второй никогда не оценивается.
пример
if(strString != null && strString.Length > 0)
Эта строка вызовет нулевое исключение, если обе стороны выполнены.
Интересная заметка. Вышеприведенный пример довольно немного быстрее, чем метод IsNullorEmpty.
Это абсолютно безопасно. С# является одним из этих языков.
Да, С# и большинство языков вычисляют предложения if слева направо.
VB6, кстати, вычислит все это и выбросит исключение, если оно будет null...
В С#, &&
и ||
закорочены, что означает, что первое условие оценивается, а остальные игнорируются, если ответ определен.
В VB.NET AndAlso
и OrElse
также закорочены.
В javaScript, &&
и ||
также закорочены.
Я упоминаю VB.NET, чтобы показать, что уродливый рыжеволосый step-child.net также иногда имеет классный материал.
Я упоминаю javaScript, потому что, если вы занимаетесь веб-разработкой, вы, вероятно, также можете использовать javaScript.