Search code examples
vb.netlinqexpression-trees

call First LINQ method


I have this:

Dim aggregator_func As MethodInfo = Nothing
aggregator_func = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
    Where(Function(m) m.Name = "First").Where(Function(m) m.ReturnType.FullName = "")(0).MakeGenericMethod(GetType(Object))
Dim groupparameter = Expression.Parameter(GetType(Linq.IGrouping(Of Object(), Object())), "g")
Dim aggregation As Expression

I would like to call this: g.First()(0)

g.First returns an object array, but I need only the object at the specified index (in this case 0). I can easily provide the index with a constant, but how could I call the above expression?

I have googled, but found nothing useful to me.

This should be complement somehow:

aggregation = Expression.Call(aggregator_func, groupparameter)

Thanks.

EDIT:

The g parameter is an Linq.IGrouping(Of Object(), Object()). That' why First returns an array of objects. Maybe, an array of objects can be called an object too, but I think, this is not important now.


Solution

  • As explained here, static methods like Enumerable.First need a null instance passed as the first argument. You also need to construct the Generic Method First properly. If you don't, the compiler won't recognize the type of aggregation as Object(), rather just as Object, and it won't compile

    Only line changed is the aggregator_func line, added last two lines.

        Dim aggregator_func As MethodInfo = Nothing
        aggregator_func = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
            Where(Function(m) m.Name = "First").Where(Function(m) m.ReturnType.FullName = "")(0).MakeGenericMethod(GetType(Object()))
        Dim groupparameter = Expression.Parameter(GetType(Linq.IGrouping(Of Object(), Object())), "g")
        Dim aggregation As Expression = Expression.Call(Nothing, aggregator_func, groupparameter)
        Dim arrayAccess As Expression = Expression.ArrayAccess(aggregation, Expression.Constant(0))