问题
In general, the short circuit or
operator ||
ignores the right side of the or if the left side evaluates to true. Apparently, we've found an exception to this.
Check out the following:
if (foo == null || bar != true ? foo.Count == 0 : true)
{
}
This code throws a null reference exception on the command foo.Count
because foo
is null. And naturally, the boolean logic allows for this. But, if foo
is null you would expect that the or
would short circuit and not even evaluate the right side of the expression, but it still does, and it throws an exception.
Is this a bug in my code or in the C# compiler? Is there a part of the C# specification that handles this case?
回答1:
That's because your statement isn't being evaluated as you expect.
You need some extra parenthesis:
if(foo == null || (bar != true ? foo.Count == 0 : true))
The way it's written now is equivalent to (due to operator precedence):
if((foo == null || bar != true) ? foo.Count == 0 : true)
回答2:
No, it works correctly, refer to operator precedence. ||
will be evaluated before ?:
So it firstly evaluates foo == null || bar != true
and then ? foo.Count == 0 : true
, so it's more like:
if ((foo == null || bar != true) ? foo.Count == 0 : true)
{
}
If you want to use short-circut here then it should be:
if (foo == null || (bar != true ? foo.Count == 0 : true))
{
}
回答3:
Imagine parentheses around the condition you're checking:
if ((foo == null || bar != true) ? foo.Count == 0 : true)
{
}
Thus, if foo
is null
, you're attempting to read foo.Count
, which will naturally result in a NullReferenceException
.
回答4:
According to Operator precedence and associativity conditional operator ?:
has lowest priority. Thus it will be executed last. Like this:
(foo == null || bar != true) ? foo.Count == 0 : true
来源:https://stackoverflow.com/questions/13313135/boolean-or-containing-ternary-conditional-operation-doesnt-get-short-circuited