为什么我可以省略调用链中后续的空条件运算符?

Why can I omit the subsequent null-conditional operators in an invocation chain?

考虑以下代码:

IEnumerable<int> xx = null;
var tt = xx?.Where(x => x > 2).Select(x => x.ToString());

它将null分配给tt。 问题是:为什么它能正常工作?

我想我必须在 Select 之前使用 ?. 作为 ?.Where(...) returns null。 此外,如果我将第二行分成两行:

IEnumerable<int> xx = null;
var yy = xx?.Where(x => x > 2);
var zz = yy.Select(x => x.ToString());

第三行会有ArgumentNullExceptionyy == null

有什么魔力? :)
如果是因为短路,没想到还能这样。

null-conditional运算符或也称为空传播运算符short-circuiting 即如果链中有一个操作:

var tt = xx?.Where(x => x > 2).Select(x => x.ToString());

returns null,然后链的其余部分停止执行。

所以在上面的例子中 Where 永远不会被调用,因为 xxnull.

至于第二个例子,你得到一个 ArgumentNullException 因为那是扩展方法的行为。在这种特定情况下,当 source 或提供的 selector 为 [=11= 时,Select 抛出 ArgumentNullException ].

是的,这是由于 short-circuiting。来自 MSDN reference:

...[T]he null-condition operators are short-circuiting. If one operation in a chain of conditional member access and index operation returns null, then the rest of the chain’s execution stops.

你的第二个例子抛出的原因是因为你有单独的未链接语句。 Short-circuiting 不能应用于多个语句。