Vb.net 表达式树中的调用和

Vb.net 表达式树中的调用和,vb.net,linq,sum,expression-trees,Vb.net,Linq,Sum,Expression Trees,我有一个疑问: 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

我有一个疑问:

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(函数(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])'
当然,还有一个参数。但是如果我删除groupparameter,我会收到另一条错误消息。我怎样才能纠正这个问题

谢谢

编辑:

下面是一个简单的控制台应用程序:

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
如您所见,我对聚合器函数做了一些更改。我想调用这个表达式:
g.Sum(函数(x)Convert.ToInt32(x(3))

我把所有的都放在一起,我只需要按正确的顺序调用变量。但我不明白


编辑:代码可以简单地复制并粘贴到vs中,以查看问题所在。

首先,您要在
可枚举
中查找方法-如果您试图使用表达式树,这不是一个好主意。你应该进去看看

接下来,您需要了解该方法是重载的,并且有多个方法返回
Int32
。您需要检查该方法是否有两个参数。请注意,您可以在单个
中检查多个条件,其中
。例如:

Where(Function(m) m.Name = "Sum" AndAlso
                  m.ReturnType = GetType(Integer) AndAlso
                  m.GetParameters().Length = 2)
希望这至少能为您找到正确的调用方法。我很难判断这一切是否都是错的(一个简短但完整的程序演示你正在尝试做的事情会有所帮助),但它至少会让你更接近

编辑:您使用的参数到处都是。例如,您有一个
i分组
——它不是
IEnumerable
——它是一个
IEnumerable
。而且您当前指定的参数顺序也不正确-扩展方法的目标是第一个参数。下面是一个简短但完整的程序,它不会引发异常:

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

另一个错误消息是什么?@derstauner:结果是什么?(不清楚为什么将它们全部作为字段,而不是Main中的局部变量,请注意……)结果是一条错误消息:“System.Func
2[System.Object[],System.Int32]”类型的表达式不能用于“System.Collections.Generic.IEnumerable
1[System.Func
2[System.Object[],System.Int32]”类型的参数方法“Int32 Sum[Func
2](System.Collections.Generic.IEnumerable
1[System.Func
2[System.Object[],System.Int32]],System.Func
2[System.Func
2[System.Object[],System.Int32],System.Int32])的'。正如我所说,我真的不知道该如何使用这个表达式。调用这个变量。是田地还是船位。变量,现在这不重要了。我只想提供一个示例。@derstauner:我用一个类似的程序编辑了我的答案,该程序不会引发异常。我想你应该从更简单的事情开始-我想你对泛型参数和参数的顺序感到困惑。我想,我现在知道了,参数的顺序是如何工作的:假设我用一个参数调用g上的Sum。谢谢。@derstauner:不,您实际上是在传递
g
和选择器函数作为参数-
Sum
是一个扩展方法。这就是为什么调用的第一个参数是
Nothing
——它是一个静态方法,所以它不被“on”任何东西调用。