-1

一般来说,短路or算子||会忽略 的右侧,或者如果左侧的计算结果为真。显然,我们发现了一个例外。

查看以下内容:

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

}

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

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

4

4 回答 4

17

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

你需要一些额外的括号:

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

现在的写法等价于(由于运算符优先级):

if((foo == null || bar != true) ? foo.Count == 0 : true)    
于 2012-11-09T17:40:27.003 回答
11

不,它可以正常工作,请参阅运算符优先级||将在之前进行评估?:

所以它首先评估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))
{

}
于 2012-11-09T17:40:42.047 回答
3

想象一下您正在检查的条件周围的括号:

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

}

因此,如果foois null,您正在尝试读取foo.Count,这自然会导致NullReferenceException.

于 2012-11-09T17:41:27.387 回答
2

根据运算符优先级和关联性,条件运算符?:的优先级最低。因此它将最后执行。像这样:

(foo == null || bar != true) ? foo.Count == 0 : true
于 2012-11-09T17:46:42.430 回答