web-dev-qa-db-ja.com

.NETでは&&短絡回路に依存していますか?

MyObjがnullであると想定します。これを書いても大丈夫ですか?

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

&&は2番目の部分が実行される前にfalseと評価されるため、一部の言語は2番目の式を実行しないことを知っています。

55
astronought

はい。 C#では、_&&_と_||_は短絡であるため、左側で結果がまだ決定されていない場合にのみ右側を評価します。一方、演算子_&_および_|_は短絡せず、常に両側を評価します。

スペックは言う:

_&&_および_||_演算子は、条件付き論理演算子と呼ばれます。これらは「短絡」論理演算子とも呼ばれます。
...
操作_x && y_は、操作_x & y_に対応します。ただし、yは、xtrueの場合にのみ評価されます
...
操作_x && y_は_(bool)x ? (bool)y : false_として評価されます。つまり、xが最初に評価され、bool型に変換されます。次に、xtrueである場合、yが評価されて型boolに変換され、これが演算の結果になります。それ以外の場合、演算の結果はfalseです。

(C#言語仕様バージョン4.0-7.12条件付き論理演算子)

_&&_と_||_の興味深いプロパティの1つは、ブール値ではなく、ユーザーが演算子_&_または_|_をオーバーロードした型であっても短絡していることです。 trueおよびfalse演算子とともに使用します。

操作_x && y_はT.false((T)x) ? (T)x : T.&((T)x, y)として評価されます。ここで、T.false((T)x)Tで宣言された_operator false_の呼び出しであり、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ユーザー定義の条件付き論理演算子)

79
CodesInChaos

はい、C#は論理短絡を使用します。

C#(および他の一部の.NET言語)はこのように動作しますが、CLRではなく言語のプロパティであることに注意してください。

14
harpo

私はパーティーに遅れていることを知っていますが、C#6.0ではこれも行うことができます。

if(myObj?.SomeString != null)

これは上記と同じです。

以下も参照してください: C#6.0での疑問符とドット演算子の意味?。

7
Drew Delano

コードは安全です-&&および||両方とも短絡しています。両端を評価する非短絡演算子&または|を使用できますが、私は実際には多くの製品コードでそれを確認していません。

4
Joe Enos

確かに、C#では安全です。最初のオペランドがfalseの場合、2番目のオペランドは評価されません。

2
Mauricio

C#では、&&および||は短絡されています。つまり、最初の条件が評価され、残りが無視されます。

VB.NETでは、AndAlsoOrElseも短絡されています。

JavaScriptでは、&&および||も短絡されています。

私はVB.NETについて言及し、.netの醜い赤毛のステップチャイルドにもクールなものがあることを示しています。

私がjavaScriptについて言及したのは、Web開発を行っている場合は、おそらくjavaScriptも使用する可能性があるためです。

0
John Grabauskas

完全に安全です。 C#はそれらの言語の1つです。

0
Ilya Kogan

はい、C#とほとんどの言語はif文を左から右に計算します。

ちなみにVB6はすべてを計算し、それがnullの場合は例外をスローします...

0
Yochai Timmer

例は

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

両方が実行された場合、この行はnull例外を引き起こします。

興味深いサイドノート。上記の例は、IsNullorEmptyメソッドよりもかなり高速です。

0
Bengie