Boolean或包含三元条件运算不会发生短路

时间:2012-11-09 17:37:54

标签: c# .net short-circuiting

通常,短路or运算符||忽略右侧或者如果左侧的计算结果为true。显然,我们发现了一个例外。

查看以下内容:

if (foo == null || bar != true ? foo.Count == 0 : true)
{

}

此代码在命令foo.Count上抛出空引用异常,因为foo为空。当然,布尔逻辑允许这样做。但是,如果foo为null,您会期望or会短路,甚至不会评估表达式的右侧,但它仍然会这样做,并且会抛出异常。

这是我的代码或C#编译器中的错误吗?是否有一部分C#规范可以处理这种情况?

4 个答案:

答案 0 :(得分:17)

那是因为您的陈述未按预期进行评估。

您需要一些额外的括号:

if(foo == null || (bar != true ? foo.Count == 0 : true))

现在写的方式相当于(由于运算符优先级):

if((foo == null || bar != true) ? foo.Count == 0 : true)    

答案 1 :(得分:11)

不,它运作正常,请参阅operator precedence。我会在||

之前评估?:

首先评估foo == null || bar != true然后评估? foo.Count == 0 : true,所以它更像是:

if ((foo == null || bar != true) ? foo.Count == 0 : true)
{

}

如果你想在这里使用短圈,那么它应该是:

if (foo == null || (bar != true ? foo.Count == 0 : true))
{

}

答案 2 :(得分:3)

想象一下你正在检查的条件的括号:

if ((foo == null || bar != true) ? foo.Count == 0 : true)
{

}

因此,如果foonull,则您尝试阅读foo.Count,这自然会产生NullReferenceException

答案 3 :(得分:2)

根据Operator precedence and associativity条件运算符?:具有最低优先级。因此它将在最后执行。像这样:

(foo == null || bar != true) ? foo.Count == 0 : true