在表达式树中调用 sum
call sum in expression tree
我有这个问题:
Dim test = result.GroupBy(Function(row) groupedindexes.Select(
Function(grpindex) row(grpindex)).ToArray, comp).
Select(Function(g) New groupedresult(g.Key, g.Sum(Function(x) Convert.ToInt32(x(3)))))
目前,我正在构建这个:g.Sum(Function(x) Convert.ToInt32(x(3)))
到目前为止我有这个:
Dim groupparameter = Expression.Parameter(GetType(Linq.IGrouping(Of Object(), Object())), "g")
Dim objectparameter = Expression.Parameter(GetType(Object()), "x")
convertMethod = GetType(System.Convert).GetMethod("ToInt32", New Type() {GetType(Object)})
Dim aggregator_expr As LambdaExpression = Expression.Lambda(expression.Call(convertMethod, Expression.ArrayAccess(objectparameter, Expression.Constant(3))), objectparameter)
Dim aggregator_func = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
Where(Function(m) m.Name = "Sum").Where(Function(m) m.ReturnType.FullName = "System.Int32").First
Dim aggregation As Expression = Expression.Call(aggregator_func, groupparameter, aggregator_expr)
在最后一行,vs 说:
Incorrect number of arguments supplied for call to method 'Int32 Sum(System.Collections.Generic.IEnumerable`1[System.Int32])'
当然,还有一个参数。但是,如果我删除组参数,则会收到另一条错误消息。我该如何纠正?
谢谢。
编辑:
这里是一个简单的控制台应用程序:
Imports System.Reflection
Imports System.Linq.Expressions
Module Module1
Dim groupparameter = Expression.Parameter(GetType(Linq.IGrouping(Of Object(), Object())), "g")
Dim objectparameter = Expression.Parameter(GetType(Object()), "x")
Dim convertMethod = GetType(System.Convert).GetMethod("ToInt32", New Type() {GetType(Object)})
Dim aggregator_expr As LambdaExpression = Expression.Lambda(
Expression.Call(convertMethod, Expression.ArrayAccess(objectparameter, Expression.Constant(3))), objectparameter)
Dim aggregator_func = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
Where(Function(m) m.Name = "Sum").Where(Function(m) m.ReturnType.FullName = "System.Int32" AndAlso m.GetParameters.Length = 2)(0).
MakeGenericMethod(GetType(System.Func(Of Object(), Integer)))
Sub Main()
Dim aggregation As Expression = Expression.Call(Nothing, aggregator_func, aggregator_expr, groupparameter)
End Sub
End Module
如您所见,我对 aggregator_func
做了一些改动。我想调用这个表达式:g.Sum(Function(x) Convert.ToInt32(x(3)))
.
我都有了,我只需要按正确的顺序调用变量即可。但我不明白。
编辑:代码可以简单地复制粘贴到vs中看看,有什么问题。
首先,您正在 Enumerable
中寻找方法 - 如果您尝试使用表达式树,这不是一个好主意。您应该查看 Queryable
.
接下来,您需要了解 Sum
方法被重载 - 并且有多个方法 return Int32
。您需要检查该方法是否有两个参数。请注意,您可以在单个 Where
中检查多个条件。例如:
Where(Function(m) m.Name = "Sum" AndAlso
m.ReturnType = GetType(Integer) AndAlso
m.GetParameters().Length = 2)
希望这至少能为您找到正确的调用方法。我不能轻易判断那是否 all 是错误的(一个简短但完整的程序演示你正在尝试做的事情会有所帮助)但它至少应该让你更接近。
编辑:您使用的参数到处都是。例如,您有一个 IGrouping<object[], object[]>
- 这不是 IEnumerable<Func<object[], int>>
- 它是一个 IEnumerable<object[]>
。而且您目前也在以错误的顺序指定参数 - 扩展方法的目标是 first 参数。所以这是一个简短但完整的程序,不会 抛出异常:
Imports System.Reflection
Imports System.Linq.Expressions
Class Test
Shared Sub Main()
Dim groupParameter = Expression.Parameter(GetType(Linq.IGrouping(Of Object(), Object())), "g")
Dim objectParameter = Expression.Parameter(GetType(Object()), "x")
Dim convertMethod = GetType(System.Convert).GetMethod("ToInt32", New Type() {GetType(Object)})
Dim aggregatorExpr As LambdaExpression = Expression.Lambda(
Expression.Call(
convertMethod,
Expression.ArrayAccess(objectParameter, Expression.Constant(3))
), objectParameter)
Dim aggregatorFunc = GetType(Enumerable) _
.GetMethods(BindingFlags.Public Or BindingFlags.Static) _
.Where(Function(m) m.Name = "Sum") _
.Where(Function(m) m.ReturnType.FullName = "System.Int32") _
.Where(Function(m) m.GetParameters.Length = 2)(0) _
.MakeGenericMethod(GetType(Object()))
Dim aggregation As Expression = Expression.Call(
Nothing,
aggregatorFunc,
groupParameter,
aggregatorExpr)
End Sub
End Class
我有这个问题:
Dim test = result.GroupBy(Function(row) groupedindexes.Select(
Function(grpindex) row(grpindex)).ToArray, comp).
Select(Function(g) New groupedresult(g.Key, g.Sum(Function(x) Convert.ToInt32(x(3)))))
目前,我正在构建这个:g.Sum(Function(x) Convert.ToInt32(x(3)))
到目前为止我有这个:
Dim groupparameter = Expression.Parameter(GetType(Linq.IGrouping(Of Object(), Object())), "g")
Dim objectparameter = Expression.Parameter(GetType(Object()), "x")
convertMethod = GetType(System.Convert).GetMethod("ToInt32", New Type() {GetType(Object)})
Dim aggregator_expr As LambdaExpression = Expression.Lambda(expression.Call(convertMethod, Expression.ArrayAccess(objectparameter, Expression.Constant(3))), objectparameter)
Dim aggregator_func = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
Where(Function(m) m.Name = "Sum").Where(Function(m) m.ReturnType.FullName = "System.Int32").First
Dim aggregation As Expression = Expression.Call(aggregator_func, groupparameter, aggregator_expr)
在最后一行,vs 说:
Incorrect number of arguments supplied for call to method 'Int32 Sum(System.Collections.Generic.IEnumerable`1[System.Int32])'
当然,还有一个参数。但是,如果我删除组参数,则会收到另一条错误消息。我该如何纠正?
谢谢。
编辑:
这里是一个简单的控制台应用程序:
Imports System.Reflection
Imports System.Linq.Expressions
Module Module1
Dim groupparameter = Expression.Parameter(GetType(Linq.IGrouping(Of Object(), Object())), "g")
Dim objectparameter = Expression.Parameter(GetType(Object()), "x")
Dim convertMethod = GetType(System.Convert).GetMethod("ToInt32", New Type() {GetType(Object)})
Dim aggregator_expr As LambdaExpression = Expression.Lambda(
Expression.Call(convertMethod, Expression.ArrayAccess(objectparameter, Expression.Constant(3))), objectparameter)
Dim aggregator_func = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
Where(Function(m) m.Name = "Sum").Where(Function(m) m.ReturnType.FullName = "System.Int32" AndAlso m.GetParameters.Length = 2)(0).
MakeGenericMethod(GetType(System.Func(Of Object(), Integer)))
Sub Main()
Dim aggregation As Expression = Expression.Call(Nothing, aggregator_func, aggregator_expr, groupparameter)
End Sub
End Module
如您所见,我对 aggregator_func
做了一些改动。我想调用这个表达式:g.Sum(Function(x) Convert.ToInt32(x(3)))
.
我都有了,我只需要按正确的顺序调用变量即可。但我不明白。
编辑:代码可以简单地复制粘贴到vs中看看,有什么问题。
首先,您正在 Enumerable
中寻找方法 - 如果您尝试使用表达式树,这不是一个好主意。您应该查看 Queryable
.
接下来,您需要了解 Sum
方法被重载 - 并且有多个方法 return Int32
。您需要检查该方法是否有两个参数。请注意,您可以在单个 Where
中检查多个条件。例如:
Where(Function(m) m.Name = "Sum" AndAlso
m.ReturnType = GetType(Integer) AndAlso
m.GetParameters().Length = 2)
希望这至少能为您找到正确的调用方法。我不能轻易判断那是否 all 是错误的(一个简短但完整的程序演示你正在尝试做的事情会有所帮助)但它至少应该让你更接近。
编辑:您使用的参数到处都是。例如,您有一个 IGrouping<object[], object[]>
- 这不是 IEnumerable<Func<object[], int>>
- 它是一个 IEnumerable<object[]>
。而且您目前也在以错误的顺序指定参数 - 扩展方法的目标是 first 参数。所以这是一个简短但完整的程序,不会 抛出异常:
Imports System.Reflection
Imports System.Linq.Expressions
Class Test
Shared Sub Main()
Dim groupParameter = Expression.Parameter(GetType(Linq.IGrouping(Of Object(), Object())), "g")
Dim objectParameter = Expression.Parameter(GetType(Object()), "x")
Dim convertMethod = GetType(System.Convert).GetMethod("ToInt32", New Type() {GetType(Object)})
Dim aggregatorExpr As LambdaExpression = Expression.Lambda(
Expression.Call(
convertMethod,
Expression.ArrayAccess(objectParameter, Expression.Constant(3))
), objectParameter)
Dim aggregatorFunc = GetType(Enumerable) _
.GetMethods(BindingFlags.Public Or BindingFlags.Static) _
.Where(Function(m) m.Name = "Sum") _
.Where(Function(m) m.ReturnType.FullName = "System.Int32") _
.Where(Function(m) m.GetParameters.Length = 2)(0) _
.MakeGenericMethod(GetType(Object()))
Dim aggregation As Expression = Expression.Call(
Nothing,
aggregatorFunc,
groupParameter,
aggregatorExpr)
End Sub
End Class