VB.NET:“语句lambdas无法转换为表达式树”编译时错误

时间:2011-02-18 00:46:53

标签: .net vb.net lambda

为什么我可以执行以下操作:

Dim qNodes As IQueryable(Of XmlNode) = xDoc.ChildNodes.AsQueryable()
Dim test = qNodes.Where(Function(node) True)

虽然以下是我在标题中说明的错误:

Dim qNodes As IQueryable(Of XmlNode) = xDoc.ChildNodes.AsQueryable()
Dim test = qNodes.Where(Function(node)
                               Return True
                           End Function)

我真的不明白。

2 个答案:

答案 0 :(得分:11)

VB.Net支持两种lambda表达式:

  • 表达式lambdas 包含单个表达式并隐式返回表达式 例如:Function(x) x.ToString()

  • 语句lambdas 包含一个或多个语句,必须明确使用Return关键字(如果它们返回值)
    这些是VB.Net 2010的新功能。
    例如:

    Sub(x)
        Logger.Log(x)
        Console.WriteLine(x)
    End Sub
    

Where方法和所有其他IQueryable方法采用expression trees 编译器可以自动将表达式 lambdas,而不是语句lambdas编译到表达式树中。

您的第二个示例尝试将语句 lambda作为Expression(Of Func(Of T, Boolean))传递,但编译器无法执行此操作。

答案 1 :(得分:7)

这在VB.NET 10语言规范的第11.1节中说明:

  

lambda之间的确切翻译   方法和表达树可能不会   在版本之间修复   编译器和超出范围   这个规范。对于微软   Visual Basic 10.0,所有lambda   表达式可能会被转换为   表达树受制于   以下限制:

     
      
  1. 只有没有ByRef参数的单行lambda表达式   可以转换为表达式树。   只有单线Sub lambdas   可以转换调用语句   表达树木。
  2.   
  3. 如果是匿名类型表达式,则无法将其转换为表达式树   早期的字段初始化程序用于   初始化后续字段   初始化器,例如新的{.a = 1,   .B = .A}
  4.   
  5. 无法将对象初始值设定项表达式转换为表达式   树木如果是当前的成员   正在初始化的对象用于   一个字段初始化器,例如,   新的C1,{。a = 1,.b = .Method1()}
  6.   
  7. 多维数组创建表达式只能转换为   表达树,如果他们宣布他们的   元素类型明确。
  8.   
  9. 后期绑定表达式无法转换为表达式树。
  10.   
  11. 当变量或字段通过ByRef传递给调用时   表达,但没有完全   与ByRef参数相同的类型,   或当物业通过ByRef时,   正常的VB语义是那个副本   参数是ByRef及其传递的   然后将最终值复制回   变量或字段或属性。在   表达树,复制后   没发生。
  12.         

    所有这些限制适用于嵌套   lambda表达式也是如此。

这是您遇到的第一个项目中的限制。引言留下了足够的空间来假设这将在未来的版本中得到解决,当然还有很多工作要做。 Connect.microsoft.com是一个鼓励他们的好地方。我无法检查是否已经为此打开了一个反馈项目,该网站现在正处于fritz状态。