2010-04-22 21 views
5

Il supporto System.Reflection non (AFAIK) riflette sui metodi globali in un assieme. A livello di assembly, devo iniziare con i tipi di root.System.Reflection - Metodi globali non disponibili per la riflessione

Il mio compilatore può produrre assembly con metodi globali e il mio bootstrap lib standard è una dll che include alcuni metodi globali. Il mio compilatore utilizza System.Reflection per importare i metadati di assembly in fase di compilazione. Sembra che se dipendo da System.Reflection, i metodi globali non sono una possibilità. La soluzione più pulita è quella di convertire tutti i miei metodi standard in metodi statici di classe, ma il punto è che il mio linguaggio consente metodi globali e il CLR lo supporta, ma System.Reflection lascia un vuoto.

ildasm mostra correttamente i metodi globali, ma presumo che non utilizzi System.Reflection stesso e passi direttamente ai metadati e al bytecode.

Oltre a System.Reflection, chiunque è a conoscenza di eventuali altre librerie di riflessione o disassemblaggio di terze parti che potrei utilizzare (presumendo che alla fine rilascerò il mio compilatore come open source con licenza BSD gratuita).

RISOLTO: non c'è spazio, a parte la mia conoscenza. Grazie per aver segnalato GetModules, ragazzi!

risposta

9

Hai guardato Module.GetMethods?

restituisce i metodi globali definiti sul modulo

È possibile ottenere tutti i moduli della vostra assemblea utilizzando Assembly.GetModules().

+0

Beat me ad esso, ma devo ammettere che non ho davvero provato. Buona domanda e buona risposta. –

+1

@Brian: cosa ti fa pensare di averlo provato? ;) –

+0

probabilmente hai dell'alimentazione di alto livello che ti consente di sapere se la documentazione è accurata o meno semplicemente osservandola :) –

4

Continui a battere su uno spazio tra il CLR e System.Reflection, ma in realtà, non esiste un metodo globale o un campo globale.

Sono solo metodi statici tradizionali e campi statici definiti in un particolare tipo, denominato <Module>, che deve essere presente in ogni assembly valido.

Come detto da Jon, è possibile utilizzare Module.GetMethod e Module.GetField per l'operatore sui membri del tipo.

Se si desidera un maggiore controllo, è possibile utilizzare solo Mono.Cecil.

+1

+1 Mono.Cecil è fantastico! –

+1

Non sto "battendo nulla" tranne la mia tastiera. Ho appena perso queste informazioni, motivo per cui ho chiesto su SO. Imparo di più ogni giorno. Grazie per la risposta. :) – codenheim

+0

@Jb: Riguardo a Mono.Cecil, e ne sono consapevole e sicuramente interessato a questo. L'unica ragione per cui ho passato era la licenza. Quando rilascio il mio codice, sarà la licenza BSD.Sosterrò la costruzione di Mono, ma non posso includere una dipendenza da strumenti che non sono comuni al CLR ufficiale e Mono. Certo, questo è tutto speculativo adesso, comunque. – codenheim

2

Nota, che Module.GetMethod() senza parametri non restituirà tutti i metodi del modulo.
Utilizzare invece GetMethods (BindingFlags).

C++/CLI esempio:

#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))); 
} 
Problemi correlati