【发布时间】:2014-01-04 08:36:00
【问题描述】:
在构建表达式树时,我必须使用调用外部方法的节点来获取表达式然后可以继续评估的值。
这些方法以Func<T> 的形式提供,我的代码不知道它们的来源。
执行上述调用的最正确方法是什么?我尝试过这样的事情:
private Dictionary<string, Delegate> _externalSymbols;
private Expression _forExternalSymbol(string identifier)
{
Delegate method = _externalSymbols[identifier];
return Expression.Call(method.Method);
}
只要从字典中提取的method 是在编译时创建的,它就可以工作。但是,如果Func<T> 是动态方法,例如通过在运行时编译另一个表达式,这将无法抛出
ArgumentException:为调用方法“Int32 lambda_method(System.Runtime.CompilerServices.ExecutionScope)”提供的参数数量不正确
可以通过将给定函数包装到一个额外的表达式中来实现所需的效果,但与过去的样子相比,这似乎相当可怕:
private Expression _forExternalSymbol(string identifier)
{
Delegate method = _externalSymbols[identifier];
Expression mediator = method is Func<double> ?
(Expression)(Expression<Func<double>>)(() => ((Func<double>)method)()) :
(Expression<Func<string>>)(() => ((Func<string>)method)());
return Expression.Invoke(mediator);
}
此外,如果我需要添加对 double 和 string 以外的类型的支持,这几乎不是一种可扩展的方法。
我想知道是否有更好的选项可用于动态创建的方法(最好适用于 .NET 3.5)。
【问题讨论】:
-
论据呢?这些方法是否接受任何参数?
-
@nightwatch 无参数,字典保证只包含
Func<T>代表,T 为double或string(这些类型的列表将来可能需要扩展)。跨度> -
我不太懂 linq 表达式,抱歉。但是你所做的看起来像是一个动态调用,方法名称在运行时被解析。也许您可以只使用动态对象作为外部函数的接口?
标签: c# .net-3.5 expression-trees dynamicmethod dynamic-method