我知道我可以使用MethodInfo.GetMethodBody()在方法中迭代所有本地定义的变量.LocalVariables。
但是如果我将方法定义为:
public static void somemethod( int someint )
{
int test = 1;
HM.M(() =>
{
test = 2;
});
}
匿名方法可以访问someint并测试为闭包,但GetMethodBody()。LocalVariables将为空。
有没有办法使用反射来检测闭包?
答案 0 :(得分:1)
好吧,我找到了答案。编译器使用编译器生成的类实现c#中的闭包。编译器生成一个类,在该类中复制将在方法中可访问的所有变量,并且方法本身封装在此类中。外部变量值将复制到类中。
因此,在上面的示例中,M方法具有签名:
public void M( Action method )
获取闭包列表的步骤是:
MethodInfo mi = method.Method;
FieldInfo[] fields = mi.DeclaringType.GetFields
(
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.Static
);
DeclaringType将是用于实现闭包的编译器生成的类。
在fields数组中,将列出所有闭包。
获取闭包的VALUES是另一回事,但它不是这个问题的一部分。
编辑: 正如@leppie所指出的,获取值很简单:
object res = fields[ 0 ].GetValue( method.Target );