簡體   English   中英

如何使用MethodInfo調用非靜態的lambda方法(使用<> c__DisplayClass1)

[英]How to invoke lambda method that is non-static using MethodInfo (uses <>c__DisplayClass1)

請考慮以下代碼:

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

調用lambda2Method導致System.Reflection.TargetException

非靜態方法需要目標。

這里的這個問題解釋了為什么lambda1Method是靜態的,而lambda2Method是非靜態的。 基本上,如果lambdas包含局部變量,則動態創建一個類,將每個局部變量解釋為一個字段。 lambda2Method成為該新類的實例方法。 我知道這是因為lambda2Method.DeclaringType<>c__DisplayClass1 ,而lambda2Method.IsStaticfalse

我的問題是,我怎樣才能做到這一點? 我理解因為lambda2Method是非靜態的,我需要為MethodBase.Invoke()object obj參數提供一個值,它需要是<>c__DisplayClass1一個實例,但是我如何獲得這個實例呢?

您需要解決的主要問題是如何創建由編譯器生成的類型的實例?

因此,如果您真的必須使用MethodInfo ,那么您可以使用Reflection創建所需的實例:

var instance = Activator.CreateInstance(lambda2Method.DeclaringType);

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

摘要:

方法lambda2的聲明類型是編譯器生成的隱藏類。 MethodInfo.Invoke需要該類型的目標實例來調用非靜態方法。

編輯:

要使捕獲的myVariable值正確,您可以使用Target屬性:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM