一般来说,如果左侧的计算结果为
||
,逻辑“或”运算符 true
的短路行为会忽略表达式的右侧。显然,使用三元作为右侧表达式是该规则的一个例外:
List<int> foo = null;
bool bar = false;
if (foo == null || bar != true ? foo.Count == 0 : true)
{
// ...Conditional code...
}
此代码在
NullReferenceException
上抛出 foo.Count
,因为 foo
为空。当然,布尔逻辑允许这样做。但是,如果 foo
为空,您可能会期望“或”会短路,甚至不计算表达式的右侧,但它仍然如此,因此它会抛出异常。
这是我的代码或 C# 编译器中的错误吗? C# 规范中是否有部分可以处理这种情况?
那是因为您的陈述没有按照您的预期进行评估。
您需要一些额外的括号:
if(foo == null || (bar != true ? foo.Count == 0 : true))
现在的写法相当于(由于运算符优先级):
if((foo == null || bar != true) ? foo.Count == 0 : true)
不,它可以正常工作,请参阅运算符优先级。
||
将在?:
之前进行评估
所以它首先评估
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))
{
}
想象一下您正在检查的条件周围有括号:
if ((foo == null || bar != true) ? foo.Count == 0 : true)
{
}
因此,如果
foo
是 null
,则您正在尝试读取 foo.Count
,这自然会导致 NullReferenceException
。