Listing (detecting) closures in a method using reflection

I know I can iterate over all the locally defined variables in a method using the MethodInfo.GetMethodBody () method. LocalVariables.

But if I define the method as:

public static void somemethod( int someint )
{
    int test = 1;

    HM.M(() =>
    {
        test = 2;
    });
}

      

Anonymous method can access someint and check as a closure, but GetMethodBody (). Local variables will be empty.

Is there a way to use reflection to detect closures?

+3


source to share


1 answer


Well I found the answer. Closures in C # are implemented by the compiler with a compiler-generated class. The compiler creates a class in which it copies all the variables that will be available in the method, and the method itself is encapsulated in this class. The values ​​of external variables are copied to the class.

So, in my example above, the M method is signed:

public void M( Action method )

      

To get a list of closures, follow these steps:

MethodInfo mi = method.Method; 

FieldInfo[] fields = mi.DeclaringType.GetFields
                                    (
                                        BindingFlags.NonPublic |
                                        BindingFlags.Instance |
                                        BindingFlags.Public |
                                        BindingFlags.Static
                                    );

      



DeclaringType will be the compiler-generated class used to implement closures.

All closures will be listed in the field array.

Getting the VALUES of closures is another story, but it is not part of this question.

EDIT: As @leppie pointed out, getting the values ​​is easy:

object res = fields[ 0 ].GetValue( method.Target );

      

+1


source







All Articles