2010-04-22 10 views
5

System.Reflection no admite (AFAIK) que refleje métodos globales en un ensamblaje. En el nivel de ensamblaje, debo comenzar con los tipos de raíz.System.Reflection: los métodos globales no están disponibles para la reflexión

Mi compilador puede producir ensambles con métodos globales, y mi lib de arranque estándar es una DLL que incluye algunos métodos globales. Mi compilador usa System.Reflection para importar metadatos ensamblados en tiempo de compilación. Parece que si dependo de System.Reflection, los métodos globales no son una posibilidad. La solución más limpia es convertir todos mis métodos estándar en métodos estáticos de clase, pero el punto es que mi lenguaje permite métodos globales y CLR lo admite, pero System.Reflection deja un espacio.

ildasm muestra bien los métodos globales, pero supongo que no usa System.Reflection y va directamente a metadatos y códigos de bytes.

Además de System.Reflection, ¿alguien conoce otras libs de reflexión o desensamblaje de terceros que pueda utilizar (suponiendo que eventualmente lanzaré mi compilador como fuente abierta de licencia BSD gratuita).

SOLUCIONADO: No hay espacio, excepto en mi conocimiento. Gracias por señalar GetModules, muchachos!

Respuesta

9

¿Has mirado Module.GetMethods?

devuelve los métodos globales definidas en el módulo

Usted puede obtener todos los módulos de su montaje utilizando Assembly.GetModules().

+0

se me adelantó, pero tengo que admitir que no he hecho probado. Buena pregunta y buena respuesta. –

+1

@Brian: ¿Qué te hace pensar que lo he probado? ;) –

+0

es probable que tenga algún poder de alto nivel que le permita saber si la documentación es precisa o no, simplemente mirándola :) –

4

Seguimos golpeando un espacio entre CLR y System.Reflection, pero en realidad no existe un método global ni un campo global.

Son simplemente métodos estáticos tradicionales y campos estáticos que se definen en un tipo particular, denominado <Module>, que debe estar presente en todos los ensamblajes válidos.

Como dijo Jon, puede usar Module.GetMethod y Module.GetField al operador en los miembros del tipo.

Si quiere tener más control, puede simplemente usar Mono.Cecil.

+1

+1 Mono.Cecil es genial! –

+1

No estoy "ganando nada", excepto mi teclado. Me perdí esta información, por lo que pregunté por SO. Aprendo más todos los días Gracias por la respuesta. :) – codenheim

+0

@Jb: Respecto a Mono.Cecil, y estoy al tanto y seguramente interesado en ello. La única razón por la que pasé por alto fue la licencia. Cuando publique mi código, será licencia BSD.Respaldaré construir contra Mono, pero no puedo incluir una dependencia en ninguna herramienta que no sea común para el CLR oficial y el Mono. Por supuesto, eso es todo especulativo en este momento, de todos modos. – codenheim

2

Tenga en cuenta que Module.GetMethod() sin parámetros no devolverá todos los métodos del módulo.
Use GetMethods (BindingFlags) en su lugar.

ejemplo 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))); 
} 
Cuestiones relacionadas