对未来访问者的注意:此问题基于错误的repro代码。 ?.
运算符确实短路。您现在可以关闭此浏览器标签。
网上有很多来源声称空条件运算符(?.
)短路(例如http://www.informit.com/articles/article.aspx?p=2421572,搜索“电路”)。我无法发现任何这样的事情:
static void Main()
{
var c = new C();
Console.WriteLine(c?.Inner?.Inner); //does not rely on short circuiting, works
Console.WriteLine(c?.Inner.Inner); //throws NullReferenceException
}
class C
{
public C Inner;
}
此处,由于第二行?.
,第一行。第二个?.
将null视为其第一个操作数,因此也返回null。这不是短路。
显然,即使触发了null case,链的其余部分也会执行。链条没有中止。对我来说,短路意味着链条中止。 MSDN claims this is the case但代码示例并未证明短路:
//The last example demonstrates that the null-condition operators are short-circuiting
int? count = customers?[0]?.Orders?.Count();
// null if customers, the first customer, or Orders is null
在C#6开发周期中,这种行为是否曾经发生过变化?这可以解释网络上的不良消息来源。 为什么会有这么多关于短路的讨论呢?我可能会在这里误解一些东西。
This不是重复的,因为它是关于操作员是否短路(答案:否,尽管接受的答案没有说明)。 This candidate是关于无效的布尔值,否则无关。
答案 0 :(得分:6)
它确实短路(如果我们的意思是"终止呼叫链)。
考虑以下代码:
using System;
namespace ConsoleApplication1
{
class C
{
public C Inner
{
get
{
Console.WriteLine("Inner called.");
return this; // Change this to `return null;`
}
}
}
class Program
{
static void Main(string[] args)
{
var c = new C();
var x = c?.Inner?.Inner?.Inner;
}
}
}
运行它,它将打印
Inner called.
Inner called.
Inner called.
现在将return this;
更改为return null;
,然后会打印
Inner called.
从而证明调用链在第一个空值处停止。
现在将表达式更改为:
var x = c?.Inner?.Inner.Inner;
它仍会打印
Inner called.
因为它正在被短路。
显然,它必须至少访问一次Inner
以查看它是否为空。如果c
本身为空,则根本不会访问Inner
。
请注意,给出表达式:
var x = c?.Inner.Inner;
它会在第一次使用.Inner
时给出空引用异常,因为它已使用c
检查c?
不为空,现在继续使用{{1} }}
如果.Inner
为空,则由于c
,它根本不会继续访问.Inner
。
答案 1 :(得分:2)
这里的短路意味着当你有例如obj?.Property1?.Property2?.Property3
而obj
是null
时,整个表达式返回null并且没有其他属性被调用(因为它们将抛出)。 / p>
每个?.
都会发生短路,具体取决于哪个部分为null
。如果obj
不是空的,而第一个Property
则只有其他2个不会被调用。第二个相同,等等。
被短路的是表达式,而不是该表达式之后的其余语句。
答案 2 :(得分:0)
简单来说,短路是一种保证,如果它确定一个属性为空,它就不会继续尝试评估其余属性。
对于不涉及null运算符的示例,可能会更清楚。
在下面的示例中,我们在检查其属性值之前,先检查x
是否为null。
if(x != null & x.SomeProperty == 1)
但如果x
为空,这仍然会引发异常,因为它会评估这两个条件。即使x
为空,它仍然会尝试检查x.SomeProperty
并且它会抛出NullReferenceException
。
但是如果我们使用&&
运算符
if(x != null && x.SomeProperty == 1)
然后它"短路。"如果第一个条件不是真的那么它甚至不会评估第二个条件。它正在检查它们是否都是真的。但如果第一个不是真的那么它们都不可能都是真的 - 第二个的价值并不重要。所以它在第一个条件之后停止。
短路最终意味着如果它评估任何使剩余条件无关的东西,则保证不评估剩余条件。