В вашем выражении отсутствует тип приведений.Для его компиляции вам нужно явно преобразовать object
в inputServiceType
и так далее.Попробуйте этот код:
var objType = typeof(object);
var instance = Expression.Parameter(objType, "serviceInstance");
var input = Expression.Parameter(objType, "inputData");
var call = Expression.Call(
Expression.Convert(instance, inputServiceType), // convert first arg
methodInfo,
Expression.Convert(input, inputType)); // and second
var body = Expression.Convert(call, objType); // and even return type
var lambdaFunc = Expression.Lambda<Func<object, object, object>>(body, instance, input).Compile();
return lambdaFunc;
Попробуйте здесь
РЕДАКТИРОВАТЬ Вы можете сделать его более безопасным для типов:
public static Func<TService, TInput, TReturn>
CreateTypedLambdaExpression<TService, TInput, TReturn>(
string methodName)
{
var inputServiceType = typeof(TService);
var methodInfo = inputServiceType.GetMethod(methodName);
var inputType = typeof(TInput);
// now you need to check if TInput is equal to methodInfo.GetParameters().First().ParameterType
// same check for return type
var instance = Expression.Parameter(inputServiceType, "serviceInstance");
var input = Expression.Parameter(inputType, "inputData");
var call = Expression.Call(instance, methodInfo, input);
var lambdaFunc = Expression.Lambda<Func<TService, TInput, TReturn>>(call, instance, input);
return lambdaFunc.Compile();
}
Использование:
var func = CreateTypedLambdaExpression<Program, bool, int>("TestMethod");
var result = func(service, false);