当前位置: 首页 > 编程语言 > C#

编译lambda表达式会导致委托使用闭包参数分享

时间:2023-04-11 11:39:31 C#

编译lambda表达式会导致委托使用闭包参数当我使用Expression.Lambda(...).Compile()从表达式树创建委托时,结果是一个委托,它的第一个参数是一个闭包。publicstaticFuncCreateTest(){ParameterExpressiona=Expression.Parameter(typeof(T));ParameterExpressionb=Expression.Parameter(typeof(T));表达式加法=Expression.Add(a,b);return(Func)Expression.Lambda(addition,a,b).Compile();}...//'addition'等于//Int32lambda_method(//System.Runtime.CompilerServices.Closure,//Int32,//Int32)Funcaddition=DelegateHelper.CreateTest();int结果=加法(5,5);我可以很容易地通过普通代码调用委托而无需传递Closure对象,但是这个Closure是从哪里来的呢?如何动态调用这个委托?//以下不起作用。//异常:MethodInfo必须是运行时MethodInfo对象。MethodInfoadditionMethod=addition.Method;intresult=(int)additionMethod.Invoke(null,newobject[]{5,5});使用表达式树,看起来我必须传递Closure对象。PropertyInfomethodProperty=typeof(Delegate).GetProperty("方法",typeof(MethodInfo));MemberExpressiongetDelegateMethod=Expression.Property(Expression.Constant(addition),methodProperty);FuncgetMethodInfo=(Func)Expression.Lambda(getDelegate)编译();//为调用方法提供的参数数量不正确//'Int32lambda_method(System.Runtime.CompilerServices.Closure,Int32,Int32)'Expressioncall=Expression.Call(getMethodInfo(),Expression.Constant(5),Expression.常量(5));这是一个简单的例子,本身没有意义。我真正想要实现的是能够用Func包装例如FuncFunc。我已经可以为非嵌套代理执行此操作。如此处所述,这在反射期间非常有用。我应该如何正确初始化此Closure对象,或者如何防止它存在?你看到的闭包类型是一个实现细节。MSDN很清楚:此API支持.NETFramework基础结构,不能直接在您的代码中使用。表示动态生成的方法的运行时状态。表达式树可以有状态。Closure实例将包含由lambda表达式关闭的所有非文字常量。它还可以包含表达式树中嵌套lambda的委托链。为此,表达式树编译器使用了一个可爱的小技巧。它使用DynamicMethod生成内存中代码,根据定义是静态的。但是,他们正在创建一个“关闭其第一个参数”的委托。这意味着CLR会将委托的目标字段作为第一个参数传递给静态方法,因此您不必这样做。有效地隐藏您的Closure参数。您的问题的解决方案很简单,不要尝试在使用反射时调用方法、调用委托或使用Delegate.DynamicInvoke,或在表达式树的上下文中使用Expression.Invoke。以上就是C#学习教程:编译lambda表达式将导致委托使用Closure参数,分享所有内容。如果对你有用,需要了解更多C#学习教程,希望大家多多关注——本文来自网络收集,不代表立场,如涉及侵权,请点击右转联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢