通常,短路or
运算符||
忽略右侧或者如果左侧的计算结果为true。显然,我们发现了一个例外。
查看以下内容:
if (foo == null || bar != true ? foo.Count == 0 : true)
{
}
此代码在命令foo.Count
上抛出空引用异常,因为foo
为空。当然,布尔逻辑允许这样做。但是,如果foo
为null,您会期望or
会短路,甚至不会评估表达式的右侧,但它仍然会这样做,并且会抛出异常。
这是我的代码或C#编译器中的错误吗?是否有一部分C#规范可以处理这种情况?
答案 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)
{
}
因此,如果foo
为null
,则您尝试阅读foo.Count
,这自然会产生NullReferenceException
。
答案 3 :(得分:2)
根据Operator precedence and associativity条件运算符?:
具有最低优先级。因此它将在最后执行。像这样:
(foo == null || bar != true) ? foo.Count == 0 : true