Can I use Expression.Call for general and static methods?

I am trying to use Expression.Callfor a general static method. Unfortunately, there is no signature of the invocation method, which allows to give general type arguments and the info argument of the method.

Perhaps this is possible?

What I'm specifically trying to do is write a helper class that can dynamically sort IEnumerable(DataRow)through Linq.

Unfortunately, I have to use DataRowExtensionsto get the field that I want to sort in a Lambda expression.

The original code comes from http://aonnull.blogspot.de/2010/08/dynamic-sql-like-linq-orderby-extension.html .

The (experimental) code snippet is as follows:

//T is DataRow
Type type = typeof(T);            

IEnumerable<MethodInfo> extensions = GetExtensionMethods(Assembly.GetAssembly(typeof(DataRowExtensions)), typeof(DataRow));
ParameterExpression arg = Expression.Parameter(typeof(DataRow), "x");

//at Position 0 there is T Field<T>(string)   
MethodInfo mi = extensions.ToList()[0];

var methArg = Expression.Parameter(typeof(String), "\"" + orderByInfo + "\"");                              
MethodCallExpression expr = Expression.Call(null, mi, arg, methArg);                          
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), typeof(Object));
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);

Runtime Expression.Call, , , Field .

+4
1

, . MethodInfo for Field, , , .

T Field<T>(string)

MakeGenericMethod ,

MethodInfo mi = extensions.ToList()[0].MakeGenericMethod(typeof(object));

mi

object Field(string);

, -

//T is DataRow
Type type = typeof(T);            

IEnumerable<MethodInfo> extensions = GetExtensionMethods(Assembly.GetAssembly(typeof(DataRowExtensions)), type);//if T is DataRow not needed get typeof again

ParameterExpression arg = Expression.Parameter(typeof(DataRow), "x");

//at Position 0 there is T Field<T>(string)   
MethodInfo mi = extensions.ToList()[0].MakeGenericMethod(typeof(object));//you can change object type to needed type

var methArg = Expression.Parameter(typeof(String), orderByInfo);//if orderByInfo already string, then not needed wrap it in quotes

LambdaExpression lambda = Expression.Lambda<Func<T,string,object>>(
    Expression.Call(mi, arg, methArg), //call mi with args: arg, methArg
    arg,methArg);//pass parameters

Sidenote: , , : Param_0, Param_1 ..
.

+2

Source: https://habr.com/ru/post/1611955/


All Articles