Frage

Ich habe mehrere spezielle Methoden, und ich möchte analysieren sie in kompilierten Assembly aufruft.

Beispiel:

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();
}

Von diesem kompilierten Code ich mag die Argumentwerte { „Array erstellen sollte“, MyClass „mit festgelegter Größe.“ }. Ich habe versucht, den Einsatz Cecil von Mono, und ich fand die Anweisungen zum Aufruf „ToDo“ -Methode. Aber jetzt bin ich verwirrt, wie Befehl mit dem Argument Werte zu identifizieren.

ich weiß, kann es komplexe Situation, und einige Wert Argument kann nicht aufgelöst werden. Aber ich brauche nur konstante Werte lösen -. Es für meine Zwecke reicht

Danke.

EDIT: Die „ToDo“ Methode (und ähnliche) als Alternative zur Kommentar (//, / * ... * /), und nach der Kompilierung verwendet werden, sollten IL für Beton Montag analysiert und automatisch generierte Dokumentation und To-do-Liste stehen.

War es hilfreich?

Lösung

Die Codegenerierung ist etwas verwirrend, sondern kann in einfachen Fällen getan werden:

Compilierung:

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

(Hinzufügen von "x", um es zu zwingen, eine params Überlastung zu verwenden)

gibt

.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 
}

So was Sie tun müssen, ist das il analysieren die Argumente zu erkennen, die in die Compiler erzeugte Array geschoben. ein heristic, die zerbrechlich ist, aber kann es ausreichend sein, zu sagen:

  1. finden rufen zu 'meine Methode'.
  2. findet nächstes vorheriges newarr Objekt
  3. Nehmen Sie alle ldstr und ldtoken zwischen diesen und annehmen, dass sie die Argumente.

Dies ist rau, aber kann für Ihre Bedürfnisse ausreichen.

Ein AOP Stil Ansatz erhalten Sie, was Sie auf wollen Laufzeit , indem Sie einfach jeden Anruf instrumentieren die Werte Dump aber sompile Zeit über dem Ansatz ist die einzige nur die IL gegeben realistische Option.

Der Code erzeugt werden kann, sehr unterschiedlich in Release baut, wird nicht möglich sein, die automatisch generierten Array Verse jemand zu erkennen ausdrücklich es selbst zu schaffen (die von der Aufrufstelle weiter entfernt sein kann oder sogar in einer anderen Verfahren / Baumeister / Klasse .

Proviso

Ich sollte nach dem Bearbeiten beachten Sie, warum diese das Attribut basierte Anmerkungen sind eine weit bessere Lösung tun wollen, kann ich nicht sehen, warum diese in dem Verfahren tun möchte, wenn Sie es direkt Attribut kann ...

Andere Tipps

Ich bin nicht sicher, was du meinst. Beachten Sie jedoch, dass Ihre Funktion wirklich nur bekommt ein Argument: ein Array. Das ist, was Sie in IL bekommen, auch. Innerhalb die Funktion, können Sie durch das Feld gehen ihre Werte zu erhalten:

public static void ToDo( params object[] info ) {
    foreach (object x in info)
        Console.WriteLine(x);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top