Getting MethodInfo from a generated IEnumerator type

95 Views Asked by At

I'm trying to gather the attributes applied to an IEnumerator method based off an instance of the enumerator. For example:

static class Program {
    [SomeAttribute("Hello")]
    static IEnumerator Test() {
        yield return 1;
        yield return "x";
    }

    static void Main() {
        var foo = Test();
        // ... How to get the attribute from the 'foo' instance?
    }
}

foo.GetType() returns the generated type Program.<Test>d__4, so it seems to be somewhat aware of the method that generated it. How can I work backwards to find the MethodInfo of Test? From there I can get the attribute.

I also tried searching through the Program type, at each of it's methods' MethodInfo.ReturnType property to find one which returns Program.<Test>d__4. To my surprise, the MethodInfo I want just indicates a System.Collections.IEnumerator return type.

Maybe someone who understands the internals a little better can explain how I could get the MethodInfo from the generated type or vice versa.

Thanks.

1

There are 1 best solutions below

0
On

There is no reliable way. The best you can do directly with reflection is follow the compiler's convention and extract the method name and owning class from the generated type.

Once the compiler has rewritten the iterator method, the code winds up in a class that's like any other, and in theory could be instantiated and used by any other code anywhere. That it's in practice not ever used by any other code is immaterial; there's not any well-defined link from the code back to the code that actually created it.

Your other option is to actually decompile every single method in the assembly, looking for the one that in fact instantiates the generated type. That's a whole other challenge in and of itself; .NET doesn't provide a convenient way to accomplish that. And it's not exactly the most efficient way to approach the problem, whatever the problem actually is.

It seems to me that you would be better-served by asking a question that illustrates why you have this attribute in the first place and how you want to use it. It's very likely that there's a completely different alternative that doesn't require backtracking from the actual iterator's compiler-generated state machine.