为什么不能在 lambda 表达式中使用 null 传播操作符?

我经常在我的代码中使用 null 传播操作符,因为它提供了更多可读的代码,特别是在长查询中,我不必对每个使用的类进行 null 检查。

下面的代码抛出一个编译错误,我们不能在 lambda 中使用 null 传播操作符。

var cnt = humans.AsQueryable().Count(a => a.House?[0].Price == 5000);

错误是:

错误 CS8072表达式树 lambda 可能不包含空传播操作符。

C # 可以很容易地将上面的代码转换成下面的代码,如果真的不能做其他任何事情!

var cnt = humans.AsQueryable().Count(a => a.House != null && a.House[0].Price == 5000);

我很好奇为什么 C # 什么都不做,只是抛出一个编译器错误?

35642 次浏览

It's complicated since expression tree lambdas (unlike delegate lambdas) are interpreted by already existing LINQ providers which don't yet support null propagating.

Converting to a conditional expression is not always accurate as there are multiple evaluations while with ?. there's only a single evaluation for example:

customer.Where(a => c.Increment()?.Name) // Written by the user
customer.Where(a => c.Increment() == null ? null : c.Increment().Name) // Incorrectly interpreted by an old LINQ provider

You can go deeper in the relevant discussion on CodePlex where 3 solutions are offered: NullPropagationExpression, ConditionalExpression & a hybrid