Получение MethodInfo из сгенерированного типа IEnumerator

Я пытаюсь собрать атрибуты, применяемые к методу IEnumerator, на основе экземпляра перечислителя. Например:

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() возвращает сгенерированный тип Program.<Test>d__4, поэтому кажется, что он в некоторой степени осведомлен о методе, который его сгенерировал. Как я могу работать в обратном направлении, чтобы найти MethodInfo Test? Оттуда я могу получить атрибут.

Я также попытался выполнить поиск по типу Program в свойстве MethodInfo.ReturnType каждого из его методов, чтобы найти тот, который возвращает Program.<Test>d__4. К моему удивлению, MethodInfo, который я хочу, просто указывает тип возвращаемого значения System.Collections.IEnumerator.

Может быть, кто-то, кто немного лучше понимает внутренности, может объяснить, как я могу получить MethodInfo из сгенерированного типа или наоборот.

Спасибо.


person 0x80240400    schedule 14.04.2021    source источник


Ответы (1)


Нет надежного способа. Лучшее, что вы можете сделать непосредственно с отражением, — это следовать соглашению компилятора и извлечь имя метода и класс-владелец из сгенерированного типа.

После того как компилятор переписал метод итератора, код оказывается в классе, подобном любому другому, и теоретически может быть создан и использован любым другим кодом где угодно. То, что на практике он никогда не используется каким-либо другим кодом, не имеет значения; нет четко определенной связи между кодом и кодом, который фактически его создал.

Другой вариант — фактически декомпилировать каждый отдельный метод в сборке в поисках того, который фактически создает экземпляр сгенерированного типа. Это совершенно другая проблема сама по себе; .NET не предоставляет удобного способа сделать это. И это не самый эффективный способ решения проблемы, какой бы она ни была на самом деле.

Мне кажется, будет лучше, если вы зададите вопрос, который иллюстрирует, почему у вас вообще есть этот атрибут и как вы хотите его использовать. Весьма вероятно, что существует совершенно другая альтернатива, не требующая возврата из конечного автомата, сгенерированного компилятором фактического итератора.

person Peter Duniho    schedule 14.04.2021