17

C#での短絡ステートメントに関する簡単な質問です。次のようなifステートメントを使用します。

if (MyObject.MyArray.Count == 0 || MyObject.MyArray[0].SomeValue == 0)
{

//....
}

「MyArray.Count」の部分が真の場合、評価が停止することは保証されていますか?そうしないと、2番目の部分でnull例外が発生します。

4

6 に答える 6

36

はい、これは保証されています。

C#言語仕様-7.11条件付き論理演算子

&&and||演算子は、条件付き論理演算子と呼ばれます。これらは「短絡」論理演算子とも呼ばれます。

したがって、それらは定義上論理的な短絡をサポートします-あなたはこの振る舞いに頼ることができます。

ここで、条件演算子と論理演算子を区別することが重要です。

  • 条件演算子のみが短絡をサポートし、論理演算子はサポートしません。
  • C#の論理演算子は、条件付きの演算子と同じように見えますが、文字が1つ少ないため、論理ORは|であり、論理ANDは&です。
  • 論理演算子はオーバーロードできますが、条件演算子はオーバーロードできません(条件演算子の評価にはオーバーロード解決が含まれ、このオーバーロード解決は型の論理演算子のカスタムオーバーロードに解決できるため、これは少し専門的です。したがって、この制限を回避できます。ある程度)。
于 2010-04-22T15:28:13.630 に答える
12

はい、保証されています。

http://msdn.microsoft.com/en-us/library/6373h346%28v=VS.80%29.aspx

条件付きOR演算子(||)は、boolオペランドの論理ORを実行しますが、必要な場合にのみ2番目のオペランドを評価します。

于 2010-04-22T15:28:24.237 に答える
5

はい、保証されていますが、MyArrayがnull(または明らかにMyObject)の場合でも、null参照例外を取得できます。

于 2010-04-22T15:31:48.387 に答える
2

ほんの少しの観察。

あなたはこれを言いました:

そうしないと、2番目の部分でnull例外が発生します。(私の強調)

実際、これは真実ではありません。短絡が保証されていない場合IndexOutOfRangeExceptionは、2番目の部分で取得することができます。

オブジェクトの最初の項目が実際にnullである場合(またはその式の他のオブジェクトのいずれかがnullである場合)、を取得できる可能性があります。NullReferenceExceptionMyArray

唯一の完全に安全なチェックはこれです:

bool conditionHolds =
    MyObject == null ||
    MyObject.MyArray == null ||
    MyObject.MyArray.Count == 0 ||
    MyObject.MyArray[0] == null ||
    MyObject.MyArray[0].SomeValue == 0;

if (conditionHolds)
{
    //....
}
于 2010-04-22T16:19:04.820 に答える
2

はい、

AND演算の場合、オペランドのいずれかがfalseと評価され、式全体がfalseと評価された場合、残りの式を評価する必要はありません。OR演算の場合、オペランドのいずれかがtrueと評価された場合、残りの評価はスキップできます。

したがって、&&または||を使用します 演算子を使用すると、すべてのサブ式を評価せずに、式全体をtrueまたはfalseに評価できます。

しかし、その副作用も考慮してください。 この記事は、実際の例をいくつか使用して、短絡評価を詳細に理解するのに役立つ場合があります。

于 2016-05-01T06:59:57.983 に答える
-1

ネガティブ(エラーにアイテムが含まれていない)ではなく、ポジティブ(配列にアイテムが含まれている)をテストするため、&&演算子を使用することをお勧めします。

if (MyObject.MyArray.Count > 0 && MyObject.MyArray[0].SomeValue == 0) 
{ 

//.... 
} 

これも短絡することが保証されています。

于 2010-04-22T15:36:03.350 に答える