为什么我不能在lambda表达式中使用null传播运算符?

Moh*_*kar 94 .net c# compiler-errors c#-6.0 null-propagation-operator

我经常在我的代码中使用null传播运算符,因为它给了我更多可读代码,特别是在长查询中我不必对每个使用的类进行空值检查.

以下代码抛出一个编译错误,我们不能在lambda中使用null传播运算符.

var cnt = humans.AsQueryable().Count(a => a.House?[0].Price == 5000);
Run Code Online (Sandbox Code Playgroud)

错误 :

错误CS8072表达式树lambda可能不包含空传播运算符.

C#如果真的不能做任何其他事情,可以轻松地将上面的代码转换为代码到下面的代码!

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

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

i3a*_*non 63

这很复杂,因为表达式树lambdas(与委托lambdas不同)由现有的LINQ提供程序解释,这些提供程序尚不支持null传播.

转换为条件表达式并不总是准确的,因为有多个评估,而?.例如只有一个评估:

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
Run Code Online (Sandbox Code Playgroud)

您可以在相关走得更深CodePlex上的讨论,其中3个解决方案可供选择:NullPropagationExpression,ConditionalExpression和混合

  • 如果某些查询提供程序不能支持它,我当然不会感到惊讶,但这并不是没有C#语言支持它的理由. (20认同)
  • *某些*查询提供程序*尚未支持它的事实并不是禁止*所有*查询提供程序*永远*能够使用它的理由. (14认同)
  • 显然,没有查询提供者会花时间来支持处理这样的请求,直到该提供者的用户能够实际创建表示它的表达式树.为了得到支持,首先需要发生的事情是lambdas能够代表它.*存在*之后,查询提供者可以*开始*支持它,因为他们觉得这是合适的.还有很多提供商在那里做各种各样的事情.它不像EF是世界上唯一的查询提供商. (10认同)
  • `Expression`的整个*point*能够在语义上将所有C#表达式表示为代码.它的设计并不仅仅是语言的一小部分. (5认同)
  • 似乎这样仍然没有解决3年后 - 微软是否应该能够找到时间呢?他们似乎养成了使用时间和资源作为在C#中半实现新功能的借口的坏习惯. (5认同)
  • 更糟糕的是,实际上,您需要一个适用于 Linq to Sql 之类的表达式版本,以及另一个适用于内存中对象的表达式版本,否则您会收到空引用异常。‍♂️ (4认同)
  • 有很多提供程序支持EF不支持的各种功能。说没有提供者会在EF支持之前提供支持是错误的。提供程序映射到具有类似null传播语义的语言或具有简单转换的语言,该语言将具有所需的语义(提示,这两种情况对于SQL都是正确的,因此拥有EF支持将*非常*容易)比没有的时间更轻松。当然,某些组织正是由于EF不支持他们想要的功能而创建自己的查询提供程序。 (2认同)
  • 它将如何破坏当前的提供商?当前没有任何代码在lambda中使用空传播运算符,因此添加对它的支持不会破坏任何内容。您说对了,它不应该执行OP建议的翻译,因为它是无效的。它应该支持运算符,并具有一个表示它的`Expression'对象。 (2认同)
  • 有一百万种方法可以打破当前的供应商。只需将任何自定义方法插入提供程序即可破坏它。显然,如果添加支持以允许 lambda 中的空值传播,并且该代码被不支持它的提供者使用,它就会中断。并非所有 C# 代码在任何给定查询提供程序的表达式中都有效;任何使用查询提供程序的人都需要知道这一点。*这不是不在 lambdas 中实现空传播的理由*。这不是永远不会消失的东西。当前的提供商*将无法支持此功能*,直到其实施。 (2认同)
  • 这是一个先有鸡还是先有蛋的问题,如果表达式一开始不支持,提供者如何通过表达式实现对空条件运算符的支持? (2认同)
  • @i3arnon 你有关于 codeplex 的讨论的更新链接吗?我很感兴趣..非常感谢。 (2认同)