简体   繁体   中英

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 :

Non-static method requires a target.

This question here explains why the lambda1Method is static, while lambda2Method is non-static. Basically if lambdas contain local variables, a class is dynamically created that interprets each local variable as a field. lambda2Method becomes an instance method of that new class. I know this because lambda2Method.DeclaringType is <>c__DisplayClass1 , and lambda2Method.IsStatic is 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?

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:

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. MethodInfo.Invoke requires a target instance of that type to invoke a non-static method.

Edit:

To get the captured value of myVariable correct, you can make use of the Target property :

result = lambda2Method.Invoke(lambda2.Target, new object[] { 9000 });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM