вызов ToArray в запросе выбора LINQ

У меня есть этот запрос:

Dim test = result.GroupBy(Function(row) groupedindexes.Select(
                                      Function(grpindex) row(grpindex)).ToArray, comp)

Я строю дерево выражений. Я уже построил часть внутри функции GroupBy и теперь хочу вызвать метод ToArray. Вот код:

    Public Function Grouping(ByVal result As IEnumerable(Of Object()), ByVal groupedindexes As List(Of Integer), ByVal comparer As compare) As Expression
        Dim groupbyMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "GroupBy").MakeGenericMethod(GetType(Object()), GetType(System.Collections.Generic.IEqualityComparer(Of Object())))
        Dim convertMethod As MethodInfo = Nothing
        Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
        Dim indexParameter = Expression.Parameter(GetType(Integer), "grpindex")
        Dim methodstring As String
        Dim expr As Expression = Nothing
        Dim index As Integer
        Dim grpindexes As Expression = Expression.Constant(groupedindexes, GetType(System.Collections.Generic.List(Of Integer)))
        Dim selectMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Select").MakeGenericMethod(GetType(Integer), GetType(Object))
        Dim toarrayMethod2 = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "ToArray").MakeGenericMethod(GetType(Object))
        Dim cmp As Expression = Expression.Constant(comparer, GetType(compare))

        Dim fieldselector As Expressions.LambdaExpression
        fieldselector = Expression.Lambda(Expression.ArrayAccess(rowParameter, indexParameter), indexParameter)

        Dim outerfieldselector As Expressions.LambdaExpression
        outerfieldselector = Expression.Lambda(Expression.Call(selectMethod, grpindexes, fieldselector), rowParameter)

        expr = Expression.Call(groupbyMethod, Expression.Call(outerfieldselector, toarrayMethod2), cmp)
        Return expr
    End Function

Я получаю сообщение об ошибке в строке expr = ...: для статического метода требуется нулевой экземпляр, для нестатического метода требуется ненулевой экземпляр.

Я уже знаю это сообщение об ошибке, но я думаю, что вызов выражения правильный: я вызываю метод ToArray для outerfieldselector.

Вы не могли бы мне помочь? Вы можете скопировать и вставить код и протестировать его. При необходимости вы можете удалить класс сравнения.

Спасибо.


person derstauner    schedule 28.01.2015    source источник


Ответы (1)


У вас есть пара ошибок:

  1. Вы получаете неверный GroupBy метод.
  2. Вызовы методов статических методов, таких как GroupBy и ToArray, нуждаются в нулевом экземпляре, как и говорится в ошибке.

Вот исправленный код. Измененные строки — это строки, начинающиеся с expr = и outerfieldselector = и получающие метод GroupBy:

Public Function Grouping(ByVal result As IEnumerable(Of Object()), ByVal groupedindexes As List(Of Integer), ByVal comparer As compare) As Expression
    Dim groupbyMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
        Where(Function(m) m.Name = "GroupBy").
        First(Function(m) m.GetParameters().Count() = 3).
        MakeGenericMethod(GetType(Object()), GetType(Object()))
    Dim convertMethod As MethodInfo = Nothing
    Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
    Dim indexParameter = Expression.Parameter(GetType(Integer), "grpindex")
    Dim methodstring As String
    Dim expr As Expression = Nothing
    Dim index As Integer
    Dim grpindexes As Expression = Expression.Constant(groupedindexes, GetType(System.Collections.Generic.List(Of Integer)))
    Dim selectMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Select").MakeGenericMethod(GetType(Integer), GetType(Object))
    Dim toarrayMethod2 = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "ToArray").MakeGenericMethod(GetType(Object))
    Dim cmp As Expression = Expression.Constant(comparer, GetType(compare))

    Dim fieldselector As Expressions.LambdaExpression
    fieldselector = Expression.Lambda(Expression.ArrayAccess(rowParameter, indexParameter), indexParameter)

    Dim outerfieldselector As Expressions.LambdaExpression
    outerfieldselector = Expression.Lambda(Expression.Call(Nothing, toarrayMethod2, Expression.Call(selectMethod, grpindexes, fieldselector)), rowParameter)

    Dim test = Enumerable.GroupBy(result, Function(row) groupedindexes.Select(Function(grpindex) row(grpindex)).ToArray(), comparer)
    expr = Expression.Call(Nothing, groupbyMethod, Expression.Constant(result), outerfieldselector, Expression.Constant(comparer))

    Return expr
End Function
person Shlomo    schedule 28.01.2015