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

瘦欲@ 提交于 2019-12-19 11:10:59

问题


Consider the following code:

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

It assigns null to tt. The question is: why does it work properly?

I thought I must use ?. before Select as ?.Where(...) returns null. Besides, if I split the second line into two separate lines:

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

There will be the ArgumentNullException on the third line as yy == null.

What's the magic? :)
If this is because of short-circuiting, I've never thought that it can act like this.


回答1:


Yes, this is due to short-circuiting. From the 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.

The reason your second example throws is because you have separate unchained statements. Short-circuiting cannot be applied across multiple statements.




回答2:


The null-conditional operator or also known as the null propagation operator is short-circuiting i.e if one operation in the chain:

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

returns null, then the rest of the chain’s execution stops.

So in the above example Where is never invoked as xx is null.

As for the second example, you're getting an ArgumentNullException because that's the behaviour of extension methods. in this specific case, the Select throws a ArgumentNullException when the source or the provided selector is null.



来源:https://stackoverflow.com/questions/48831588/why-can-i-omit-the-subsequent-null-conditional-operators-in-an-invocation-chain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!