【发布时间】:2017-05-21 15:07:17
【问题描述】:
我有这些简单的界面:
public interface IQuery<TResult> { }
public interface IQueryHandler<in TQuery, out TResult>
where TQuery : IQuery<TResult> {
TResult Handle(TQuery query);
}
它们有一些实现。我正在尝试创建一个表达式树以在指定的处理程序上调用 Handle 方法。我的意思是:
var query = new MyQuery(); // which MyQuery implements IQuery<int>
object handler = _someServiceProvider
.Get<IQueryHandler<MyQuery, int>>();
另外,还有一个MyQueryHandler:
public class MyQueryHandler : IQueryHandler<MyQuery, int> {
public int Handle(MyQuery query) { return 20; }
}
现在,我正在尝试创建一个 Func<object, MyQuery, int> 来像这样调用:
var func = GetMethod<MyQuery, int>(handler);
var result = func(handler, query);
这是我的GetMethod 实现:
private Func<object, TQuery, TResult> GetMethod<TQuery, TResult>(object obj)
where TQuery : IQuery<TResult> {
var methodInfo = obj.GetType().GetMethod(nameof(IQueryHandler<TQuery, TResult>.Handle));
var insExp = Expression.Parameter(typeof(object), "ins");
var inputExp = Expression.Parameter(typeof(TQuery), "query");
var instanceExp = Expression.Variable(obj.GetType(), "instance");
var assExp = Expression.Assign(instanceExp, Expression.Convert(insExp, obj.GetType()));
var castExp = Expression.Convert(inputExp, methodInfo.GetParameters()[0].ParameterType);
var callExp = Expression.Call(instanceExp, methodInfo, castExp);
var blockExp = Expression.Block(new Expression[] {
insExp,
inputExp,
instanceExp,
assExp,
castExp,
callExp
});
var func =
Expression.Lambda<Func<object, TQuery, TResult>>(
blockExp,
insExp,
inputExp).Compile();
return func;
}
但是,当我尝试编译 Lambda 时,我得到了这个错误:
“System.InvalidOperationException”类型的异常发生在 System.Core.dll 但未在用户代码中处理
附加信息:变量“实例”类型 'Namespace.MyQueryHandler' 从范围''引用,但它不是 定义
我哪里错了?我错过了什么?你有什么主意吗?提前致谢。
【问题讨论】:
-
为什么需要将表达式树合并到这个?似乎过于复杂
标签: c# c#-4.0 lambda expression-trees func