【发布时间】:2015-06-18 13:16:34
【问题描述】:
我想使用表达式树来动态创建调用 lambda 的方法。以下代码在第一次调用 ComposeLambda 函数时运行良好,但第二次调用失败并显示以下错误消息。
为调用方法“Int32”提供的参数数量不正确 lambda_method(System.Runtime.CompilerServices.Closure, Int32)'
{
Func<int, int> innerLambda = i => i + 1;
var composedLambda = ComposeLambda(innerLambda);
Console.WriteLine(composedLambda.DynamicInvoke(0));
var composedLambda2 = ComposeLambda(composedLambda);
Console.WriteLine(composedLambda2.DynamicInvoke(0));
}
private static Delegate ComposeLambda(Delegate innerLambda)
{
Func<int, int> outerLambda = i => i + 2;
var parameter = Expression.Parameter(typeof (int));
var callInner = Expression.Call(innerLambda.GetMethodInfo(), parameter);
var callOuter = Expression.Call(outerLambda.GetMethodInfo(), callInner);
var composedLambdaType = typeof (Func<,>).MakeGenericType(typeof (int), typeof (int));
var composedLambdaExpression = Expression.Lambda(composedLambdaType, callOuter, parameter);
var composedLambda = composedLambdaExpression.Compile();
return composedLambda;
}
如何获取和传递这个闭包对象?
【问题讨论】:
-
@jp2code 在 4.5 中:GetMethodInfo
-
不要使用
Expression.Call(innerLambda.GetMethodInfo(), ...),那只是自找麻烦。改为调用委托——你没有任何事情搞乱委托的“方法”——你不仅失去了目标(在实例方法中非常重要),而且还侵犯了隐私(例如,匿名方法是内部的或私有的) )。在这种情况下,您没有将闭包参数传递给方法:) -
@Luaan 表达式树用来处理低级的东西——这就是它们的用途
-
好吧,显然你不知道你的“低级”东西:) 看看我的回答。
标签: c# .net linq lambda expression-trees