简体   繁体   English

如何使用MethodInfo调用非静态的lambda方法(使用<> c__DisplayClass1)

[英]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.IsStaticfalse

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.

相关问题 如何使用方法名称获取非静态MethodInfo(不在字符串中,不在类类型中搜索) - How to get non-static MethodInfo using method name (not in string, not searching in class type) 静态类中的匿名方法是非静态的? 如何调用它? - Anonymous method in static class is non-static? How to invoke it? 在编译时获取非静态方法的 MethodInfo - Getting MethodInfo at compile time for a non-static method 是什么导致C#中过多的匿名方法闭包(c__DisplayClass1)? - What causes excessive anonymous method closures (c__DisplayClass1) in C#? 为什么代码生成称为&lt;&gt; c__DisplayClass1的MSIL类 - Why Does Code Generate MSIL Class Called <>c__DisplayClass1 当存在非静态,更合适的方法时,如何使用动态参数调用静态方法? - How to invoke static method with dynamic argument when a non-static, better-fit method exists? 如何用静态方法调用非静态方法(使用WebControl)? - How do I call a non-static method (that uses a WebControl) with a static method? 获取IEnumerable的非静态MethodInfo <T> .First()(或使静态方法与EF一起使用) - Get Non-Static MethodInfo for IEnumerable<T>.First() (Or make the static method work with EF) 在静态方法中使用非静态值? - Using a non-static value in a static method? 如何从C#中的线程访问非静态方法 - How to access a non-static method from a thread in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM