Vb.net 我可以控制.NET编译器自动转换为表达式的内容吗
VB编译器自动将lambda转换为它们的Vb.net 我可以控制.NET编译器自动转换为表达式的内容吗,vb.net,linq,compiler-construction,Vb.net,Linq,Compiler Construction,VB编译器自动将lambda转换为它们的LambdaExpression等价物(例如在dima中,LambdaExpression=Function(x)x.Length)。直到最近,我还以为该特性只适用于lambdas,但后来我发现,在尝试将方法调用的结果作为参数传递给方法时,也存在同样的行为。编译器将我的调用转换为MethodCallExpression,而不是进行调用 Dim myQuery = From x In DataSource.Items Group
LambdaExpression
等价物(例如在dima中,LambdaExpression=Function(x)x.Length
)。直到最近,我还以为该特性只适用于lambdas,但后来我发现,在尝试将方法调用的结果作为参数传递给方法时,也存在同样的行为。编译器将我的调用转换为MethodCallExpression
,而不是进行调用
Dim myQuery = From x In DataSource.Items
Group By x.Key Into g = Group
Select New With {
.Key = Key,
.RedItems = g.Sum(ItemsOfColor(Colors.Red))
}
Private Function ItemsOfColor(color As Integer) As Expression(Of Func(Of Item, Integer))
Return Function(item) If(item.Color = color, 1, 0)
End Function
RedItems
包含一个MethodCallExpression
来调用itemsofolor
,使用Colors.Red
作为参数,而不是LambdaExpression
作为调用itemsofolor
的结果
问题是:为什么编译器会假设这是我想要的行为,还有,有没有办法关闭它
注意:这是一系列问题中的第三个问题,它慢慢地帮助我理解LINQ是如何编译的及其副作用。部分和。我想我终于明白了这个问题。。。这就来了。查询表达式语法(如上)显示
.RedItems=g.Sum(ItemsOfColor(Colors.Red))
是一个正常的方法调用,但不是。该“调用”实际上位于前一行的Select
语句的lambda主体内。用lambda语法重写,这将是:
.Select(Function(x) New With {
.Key = Key,
.RedItems = g.Sum(ItemsOfColor(Colors.Red))
})
这清楚地表明我们实际上已经在一个lambda里面了。负责将lambda参数转换为Select
到表达式树的编译步骤会看到对itemsofolor
的调用,并创建一个MethodCallExpression
,这正是我们所期望的
简言之,没有特殊的规则将方法调用转换为表达式,它实际上是一个lambda,我最初的问题在当前版本的EF/LINQ中是不可能的。也许有一天MS会扩展这两种方法中的一种来识别一个MethodCallExpression
,它将生成一个表达式并进行调用(从而使这种重构成为可能)