[英]How to invoke lambda method that is non-static using MethodInfo (uses <>c__DisplayClass1)
Consider the following code: 请考虑以下代码:
bool result;
Func<int, bool> lambda1 = i => i == 9000;
MethodInfo lambda1Method = lambda1.Method;
result = (bool)lambda1Method.Invoke(null, new object[] { 9000 }); // this works, result = true
int myLocalVariable = 9000;
Func<int, bool> lambda2 = i => i == myLocalVariable;
MethodInfo lambda2Method = lambda2.Method;
result = (bool)lambda2Method.Invoke(null, new object[] { 9000 }); // error
Invoking lambda2Method
results in a System.Reflection.TargetException
: 调用
lambda2Method
导致System.Reflection.TargetException
:
Non-static method requires a target.
非静态方法需要目标。
This question here explains why the lambda1Method
is static, while lambda2Method
is non-static. 这里的这个问题解释了为什么
lambda1Method
是静态的,而lambda2Method
是非静态的。 Basically if lambdas contain local variables, a class is dynamically created that interprets each local variable as a field. 基本上,如果lambdas包含局部变量,则动态创建一个类,将每个局部变量解释为一个字段。
lambda2Method
becomes an instance method of that new class. lambda2Method
成为该新类的实例方法。 I know this because lambda2Method.DeclaringType
is <>c__DisplayClass1
, and lambda2Method.IsStatic
is false
. 我知道这是因为
lambda2Method.DeclaringType
是<>c__DisplayClass1
,而lambda2Method.IsStatic
是false
。
My question is, how can I make this work? 我的问题是,我怎样才能做到这一点? I understand that because
lambda2Method
is non-static, I need to supply a value for the object obj
parameter of MethodBase.Invoke()
, and it needs to be an instance of <>c__DisplayClass1
, but how do I obtain this instance? 我理解因为
lambda2Method
是非静态的,我需要为MethodBase.Invoke()
的object obj
参数提供一个值,它需要是<>c__DisplayClass1
一个实例,但是我如何获得这个实例呢?
The main issue that you need to address in you question is How to create an instance of a type generated by the compiler ? 您需要解决的主要问题是如何创建由编译器生成的类型的实例?
So, if you really have to use MethodInfo
, then you can create the required instance by using Reflection: 因此,如果您真的必须使用
MethodInfo
,那么您可以使用Reflection创建所需的实例:
var instance = Activator.CreateInstance(lambda2Method.DeclaringType);
result = lambda2Method.Invoke(instance, new object[] { 9000 });
Summary: 摘要:
The declaring type for your method lambda2
is a hidden class generated by the compiler. 方法
lambda2
的声明类型是编译器生成的隐藏类。 MethodInfo.Invoke
requires a target instance of that type to invoke a non-static method. MethodInfo.Invoke
需要该类型的目标实例来调用非静态方法。
Edit: 编辑:
To get the captured value of myVariable
correct, you can make use of the Target
property : 要使捕获的
myVariable
值正确,您可以使用Target
属性:
result = lambda2Method.Invoke(lambda2.Target, new object[] { 9000 });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.