System.Reflection - глобальные методы недоступны для отражения

System.Reflection не поддерживает (AFAIK) отражение глобальных методов в сборке. На уровне сборки я должен начать с корневых типов.

Мой компилятор может создавать сборки с глобальными методами, а моя стандартная библиотека начальной загрузки - это библиотека DLL, которая включает некоторые глобальные методы. Мой компилятор использует System.Reflection для импорта метаданных сборки во время компиляции. Кажется, если я зависим от System.Reflection, глобальные методы не возможны. Самое чистое решение - преобразовать все мои стандартные методы в статические методы класса, но дело в том, что мой язык допускает глобальные методы, и CLR поддерживает его, но System.Reflection оставляет пробел.

ildasm прекрасно показывает глобальные методы, но я предполагаю, что он не использует сам System.Reflection и идет прямо к метаданным и байт-коду.

Помимо System.Reflection, кто-нибудь знает о любых других сторонних библиотеках рефлексии или дизассемблирования, которые я мог бы использовать (при условии, что в конечном итоге я выпущу свой компилятор как бесплатный, с открытым исходным кодом, лицензированным BSD).

РЕШЕНО: Нет пробела, кроме как в моих знаниях. Спасибо, что указали на GetModules, ребята!

3 ответа

Решение

Вы смотрели на Module.GetMethods?

Возвращает глобальные методы, определенные в модуле.

Вы можете получить все модули вашей сборки, используя Assembly.GetModules(),

Вы продолжаете биться на разрыв между CLR и System.Reflection, но на самом деле, нет такого понятия, как глобальный метод или глобальное поле.

Это просто традиционные статические методы и статические поля, которые определены в определенном типе с именем <Module>, который должен присутствовать в каждой действующей сборке.

Как сказал Джон, вы можете использовать Module.GetMethod а также Module.GetField оператор на членов типа.

Если вы хотите больше контроля, вы можете просто использовать Mono.Cecil.

Обратите внимание, что Module.GetMethod() без параметров не вернет все методы модуля.
Вместо этого используйте GetMethods(BindingFlags).

Пример C++/CLI:

#using <System.dll>
using namespace System;
using namespace System::Reflection;
using namespace System::Diagnostics;

bool has_main(array<MethodInfo^>^ methods)
{
    for each(auto m in methods)
        if(m->Name == "main")
            return true;
    return false;
}

int main()
{
    auto module = Assembly::GetExecutingAssembly()->GetModules(false)[0];
    Debug::Assert(has_main(module->GetMethods()) == false);
    Debug::Assert(has_main(module->GetMethods(BindingFlags::Static | BindingFlags::NonPublic)));
}
Другие вопросы по тегам