Domanda

Ho diversi metodi speciali, e voglio analizzare che le chiamate in assembly compilato.

Esempio:

public static class SrcHelper {
    [MySpecialMethod]
    [Conditional( "DEBUG" )]
    public static void ToDo( params object[] info ) {
        /* do nothing */
        /* this method is not called when code is compiled in RELEASE mode */
    }
}
// ... somewhere else in another assembly ...
Array CreateArraySampleMethod( int size ) {
    // This call has only informative character. No functionality is required.
    SrcHelper.ToDo( "Should create array of ", typeof( MyClass ), " with specified size." );
    throw new NotImplementedException();
}

Da questo codice compilato voglio ottenere i valori degli argomenti { "dovrebbe creare serie di" MyClass "con dimensioni specificate." }. Ho provato l'uso Cecil da Mono, e ho trovato le istruzioni per chiamata al metodo "ToDo". Ma ora sono io confuso come identificare istruzione con valori degli argomenti.

Lo so, non ci può essere complessa situazione, e il valore di qualche argomento non può essere risolto. Ma ho bisogno di risolvere solo valori costanti -. È abbastanza per il mio scopo

Grazie.

Modifica Il metodo "ToDo" (e simili) dovrebbero essere utilizzati come alternativa ai commenti (//, / * ... * /), e dopo la compilazione, devono essere IL analizzato e la documentazione generata automaticamente e todo-list per il montaggio in calcestruzzo.

È stato utile?

Soluzione

La generazione del codice è un po 'confusa, ma può essere fatto per i casi semplici:

compilazione:

public static void Main(string[] args)
{
    Console.WriteLine("", // ignore this argument
       "Should create array of ", typeof(int), " with specified size." "x");
}

(aggiungendo "x" per costringerlo ad usare un sovraccarico di params)

.method public hidebysig static void Main(string[] args) cil managed
{
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
    .maxstack 4
    .locals init (
        [0] object[] objArray)
    L_0000: ldstr ""
    L_0005: ldc.i4.4 
    L_0006: newarr object
    L_000b: stloc.0 
    L_000c: ldloc.0 
    L_000d: ldc.i4.0 
    L_000e: ldstr "Should create array of "
    L_0013: stelem.ref 
    L_0014: ldloc.0 
    L_0015: ldc.i4.1 
    L_0016: ldtoken int32
    L_001b: call class [mscorlib]System.Type 
                [mscorlib]System.Type::GetTypeFromHandle(
                    valuetype [mscorlib]System.RuntimeTypeHandle)
    L_0020: stelem.ref 
    L_0021: ldloc.0 
    L_0022: ldc.i4.2 
    L_0023: ldstr " with specified size."
    L_0028: stelem.ref 
    L_0029: ldloc.0 
    L_002a: ldc.i4.3 
    L_002b: ldstr "x"
    L_0030: stelem.ref 
    L_0031: ldloc.0 
    L_0032: call void [mscorlib]System.Console::WriteLine(string, object[])
    L_0037: ret 
}

Quindi quello che dovete fare è analizzare il il per rilevare gli argomenti di essere spinto in matrice compilatore ha generato. un heristic che è fragile, ma potrebbe essere sufficiente per dire:

  1. trova chiamata a 'il mio metodo'.
  2. trova più vicino oggetto newarr precedente
  3. prendere tutto ldstr e ldtoken tra questi, assumendo che siano gli argomenti.

Questa è ruvida, ma può essere sufficiente per le vostre esigenze.

Un approccio stile AOP si arriva quello che vuoi a runtime , semplicemente la strumentazione ogni chiamata per eseguire il dump dei valori, ma al momento sompile l'approccio di cui sopra è l'unica opzione realistica dato solo l'IL.

Il codice generato può essere molto diversa in build di rilascio, si sarà in grado di individuare l'auto ha generato serie versi qualcuno esplicitamente la creazione di loro stessi (che può essere più lontano dal sito di chiamata o anche in un diverso metodo / costruttore / classe .

Proviso

Vorrei sottolineare dopo la modifica del motivo per cui si vuole fare questo che le annotazioni di attributo base sono una soluzione di gran lunga migliore, non riesco a capire perché si vorrebbe fare questo nel metodo quando si può attribuire direttamente ...

Altri suggerimenti

Non sono sicuro di quello che vuoi dire. Tuttavia, si noti che la funzione in realtà ottiene solo una argomento: un array. Questo è quello che si ottiene in IL, anche. All'interno la funzione, si può camminare attraverso la matrice per ottenere i suoi valori:

public static void ToDo( params object[] info ) {
    foreach (object x in info)
        Console.WriteLine(x);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top