I searched the questions and found some topics and I suspect the error cause, but I can't figure it out.
I would like to build this expression part:
Function(row) groupedindexes.Select(
Function(grpindex) row(grpindex))
I already build the part Function(grpindex) row(grpindex)
with this:
Dim fieldselector As Expressions.LambdaExpression
fieldselector = Expression.Lambda(Expression.ArrayAccess(rowParameter, indexParameter), indexParameter)
The declarations are:
Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
Dim indexParameter = Expression.Parameter(GetType(Integer), "grpindex")
Now, I would like to build the Select
part like this:
Dim outerfieldselector As Expressions.LambdaExpression
outerfieldselector = Expression.Lambda(Expression.Call(grpindexes, selectMethod, fieldselector), rowParameter)
The declarations are:
Dim grpindexes As Expression = Expression.Constant(groupedindexes, GetType(System.Collections.Generic.List(Of Integer)))
Dim selectMethod = GetType(Queryable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Select").MakeGenericMethod(GetType(Object), GetType(System.Func(Of Integer, Object)))
groupedindexes
is a normal List(Of Integer)
.
In runtime, I get the above error at the line outerfieldselector=...
In my opinion, it should work. I call the Select
method on grpindexes
with one argument (fieldselector
).
What could be the problem?
Thanks.
EDIT: a sample project can be downloaded at this link: http://www.filedropper.com/exptree
EDIT II:
here a simple, short console application project:
Imports System.Reflection
Imports System.Linq.Expressions
Module Module1
Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
Dim indexParameter = Expression.Parameter(GetType(Integer), "grpindex")
Dim expr As Expression = Nothing
Dim groupedindexes As New List(Of Integer)
Dim grpindexes As Expression = Expression.Constant(groupedindexes, GetType(System.Collections.Generic.List(Of Integer)))
Dim selectMethod = GetType(Queryable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(
Function(m) m.Name = "Select").MakeGenericMethod(GetType(Object), GetType(System.Func(Of Integer, Object)))
Dim fieldselector As Expressions.LambdaExpression
Dim outerfieldselector As Expressions.LambdaExpression
Sub Main()
groupedindexes.Add(0)
groupedindexes.Add(1)
groupedindexes.Add(2)
fieldselector = Expression.Lambda(Expression.ArrayAccess(rowParameter, indexParameter), indexParameter)
outerfieldselector = Expression.Lambda(Expression.Call(grpindexes, selectMethod, fieldselector), rowParameter)
End Sub
End Module
EDIT 3:
I think, I got it with the help of svick.
Dim selectMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Select").MakeGenericMethod(GetType(Integer), GetType(Object))
The problem is that Queryable.Select()
is not an instance method. You call it as if it was one in VB, but it's not, and that's reflected in expression trees.
So, the line should look like this:
outerfieldselector = Expression.Lambda(Expression.Call(Nothing, selectMethod, grpindexes, fieldselector), rowParameter)
Even if you fix that, your code still won't work. Some of the issues are:
MakeGenericMethod()
expects the types of the type parameters. Here those are TSource
and TResult
, which should be Integer
and Object
.List(Of Integer)
does not implement IQueryable
.