为什么我可以省略调用链中后续的空条件运算符?
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());
第三行会有ArgumentNullException
为yy == null
。
有什么魔力? :)
如果是因为短路,没想到还能这样。
null-conditional运算符或也称为空传播运算符是short-circuiting 即如果链中有一个操作:
var tt = xx?.Where(x => x > 2).Select(x => x.ToString());
returns null
,然后链的其余部分停止执行。
所以在上面的例子中 Where
永远不会被调用,因为 xx
是 null
.
至于第二个例子,你得到一个 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 不能应用于多个语句。
考虑以下代码:
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());
第三行会有ArgumentNullException
为yy == null
。
有什么魔力? :)
如果是因为短路,没想到还能这样。
null-conditional运算符或也称为空传播运算符是short-circuiting 即如果链中有一个操作:
var tt = xx?.Where(x => x > 2).Select(x => x.ToString());
returns null
,然后链的其余部分停止执行。
所以在上面的例子中 Where
永远不会被调用,因为 xx
是 null
.
至于第二个例子,你得到一个 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 不能应用于多个语句。