문제

Quick question here about short-circuiting statements in C#. With an if statement like this:

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

//....
}

Is it guaranteed that evaluation will stop after the "MyArray.Count" portion, provided that portion is true? Otherwise I'll get a null exception in the second part.

도움이 되었습니까?

해결책

Yes, this is guaranteed.

C# Language Specification - 7.11 Conditional logical operators:

The && and || operators are called the conditional logical operators. They are also called the "short-circuiting" logical operators.

Therefore they will support logical short-circuiting by definition - you can rely on this behavior.

Now it is important to make a distinction between a conditional operator and a logical operator:

  • Only conditional operators support short-circuiting, logical operators do not.
  • C#'s logical operators look just like their conditional counterparts but with one less character so a logical OR is | and a logical AND is &.
  • Logical operators can be overloaded but conditional operators cannot (this is a bit of an technicality as conditional operator evaluation does involve overload resolution and this overload resolution can resolve to a custom overload of the type's logical operator, so you can work around this limitation to a certain extent).

다른 팁

Yes, it is guaranteed.

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

The conditional-OR operator (||) performs a logical-OR of its bool operands, but only evaluates its second operand if necessary.

Yes, it is guaranteed, but you can still get a null reference exception if MyArray is null (or MyObject for that matter obviously).

Just a small observation.

You said this:

Otherwise I'll get a null exception in the second part. (emphases mine)

This isn't true, actually. If short-circuiting weren't guaranteed, you could get an IndexOutOfRangeException in the second part.

It's still possible you could get a NullReferenceException, if the first item in your MyArray object is actually null (or if any of the other objects in that expression are).

The only totally safe check would be this:

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

if (conditionHolds)
{
    //....
}

Yes,

For AND operations if any of the operand evaluated to false then total expression evaluated to false then there is no need to evaluate remaining expressions, And in case of OR operation if any of the operand evaluated to true then remaining evaluation can be skipped

So by using && or || operator, whole expression can be evaluated to true or false without evaluating all sub expressions.

But consider its side effect also. This article might be helpful to understand short-circuit evaluation in depth with some real world examples.

I prefer to use the && operator, because you then test a positive (my array contains items), rather than negative (my error does not contain items):

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

//.... 
} 

This is also guaranteed to short-circuit.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top