[英]Cannot Convert between Expression<Func<…>> and Func<…>
A method I am trying to call (third party, can't change) expects a Func<TResult>
. 我尝试调用的方法(第三方,不能更改)期望
Func<TResult>
。 Using reflection I am trying to make an eg Func<Task<IEnumerable<Person>>>
but I am inadvertently creating an Expression<Func<Task<IEnumerable<Person>>>>
. 使用反射,我试图制作一个
Func<Task<IEnumerable<Person>>>
但是我无意中创建了一个Expression<Func<Task<IEnumerable<Person>>>>
。 The reason for reflection is that person is arbitrary and could be any type depending on how/when this is called. 反思的原因是,人是任意的,并且可以根据调用方式/时间的不同而定。
// trying to mimic this hard-code: () => TaskEx.FromResult(Enumerable.Empty<Person>())
//var enumerableType = typeof(Person); //potentially
var empty = (typeof(Enumerable)).GetMethod("Empty");
var genereicEmpty = empty.MakeGenericMethod(enumerableType);
var emptyEnumerable = genereicEmpty.Invoke(null, null);
var fromResult = typeof (TaskEx).GetMethod("FromResult");
var genericFromResult = fromResult.MakeGenericMethod(genereicEmpty.ReturnType);
var enumerableTask = genericFromResult.Invoke(null, new [] {emptyEnumerable});
var functype = typeof(Func<>).MakeGenericType(genericFromResult.ReturnType);
var body = Expression.Constant(enumerableTask);
var lambdaType = typeof(Expression).GetMethods()
.Where(x => x.Name == "Lambda")
.Where(x => x.GetParameters().Length == 2)
.Where(x => x.GetParameters()[1].ParameterType == typeof(ParameterExpression[]))
.Single(x => x.IsGenericMethod);
var genericLambdaType = lambdaType.MakeGenericMethod(functype);
var lambda = genericLambdaType.Invoke(null, new object[] { body, new ParameterExpression[0] });
When I use lambda later I get the exception 当我稍后使用lambda时,出现异常
Exception thrown: 'System.ArgumentException' in mscorlib.dll
Additional information: Object of type 'System.Linq.Expressions.Expression`1[System.Func`1[System.Threading.Tasks.Task`1[System.Collections.Generic.IEnumerable`1[DC.Dataloader.Models.Person]]]]' cannot be converted to type 'System.Func`1[System.Threading.Tasks.Task`1[System.Collections.Generic.IEnumerable`1[DC.Dataloader.Models.Person]]]'.
Is there a better way than Expression.Lambda
to build a Func<>
on the fly? 有没有比
Expression.Lambda
更好的方法来动态构建Func<>
? I can't seem to find the correct way to do this. 我似乎找不到正确的方法来执行此操作。
Thank you 谢谢
You're looking for the .Compile()
method, which does exactly that. 您正在寻找
.Compile()
方法,该方法正是这样做的。
Side note: 边注:
You don't need to call the Expression
APIs using Reflection; 您无需使用Reflection调用
Expression
API; you can use the non-generic Expression.Lambda()
, which will still return a Func<T>
: 您可以使用非通用的
Expression.Lambda()
,但仍将返回Func<T>
:
Expression.Lambda(body).Compile()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.