Schauen Sie, ob eine Methode innerhalb einer Methode aufgerufen wird, die reflection verwendet

8

Ich arbeite mit Reflektion und habe derzeit ein MethodBody . Wie überprüfe ich, ob eine bestimmte Methode im MethodBody aufgerufen wird?

%Vor%     
Peter 21.04.2011, 08:15
quelle

3 Antworten

17

Verwenden Sie Mono.Cecil . Es ist eine einzelne eigenständige Assembly, die sowohl mit Microsoft .NET als auch mit Mono arbeitet. (Ich glaube, ich habe Version 0.6 oder ähnliche Versionen verwendet, als ich den Code unten geschrieben habe)

Sagen Sie, Sie haben eine Anzahl von Baugruppen

%Vor%

Holen Sie diese mit AssemblyFactory (laden Sie eins?)

Das folgende Snippet würde alle Methodenverwendungen in allen Arten dieser Assemblies aufzählen

%Vor%

Dadurch werden alle Verweise auf Methoden zurückgegeben (einschließlich der Verwendung in der Reflektion oder zum Erstellen von Ausdrücken, die ausgeführt werden können oder nicht). Daher ist dies wahrscheinlich nicht sehr nützlich, außer um Ihnen zu zeigen, was mit der Cecil API ohne großen Aufwand getan werden kann:)

Beachten Sie, dass dieses Beispiel eine etwas ältere Version von Cecil (die in Mainstream-Mono-Versionen) annimmt. Neuere Versionen sind

  • prägnanter (durch Verwendung stark typisierter generischer Sammlungen)
  • schneller

Natürlich könnten Sie in Ihrem Fall eine einzige Methodenreferenz als Ausgangspunkt haben. Nehmen wir an, Sie möchten erkennen, wann 'mytargetmethod' tatsächlich direkt im 'Startpunkt' aufgerufen werden kann:

%Vor%

Anrufbaumsuche

Hier ist ein Arbeits-Snippet, mit dem Sie rekursiv nach (ausgewählten) Methoden suchen können, die einander (indirekt) aufrufen.

%Vor%

Hinweise

  • mache einen Fehler bei der Behandlung von Resolve() (Ich habe eine Erweiterungsmethode TryResolve() für den Zweck)
  • Wählen Sie optional Nutzungen von MethodReferences in einer Aufrufoperation (call, calli, callvirt ...) nur aus ( siehe //TODO )

Typische Verwendung:

%Vor%

Hinweis Die vollständige Umsetzung einer Funktion wie DetectRequestUsage, die Ihren Anforderungen entspricht, liegt vollständig bei Ihnen selbst. (Bearbeiten: aber siehe hier ). Sie können tun, was Sie wollen, und vergessen Sie nicht: Sie haben den kompletten statisch analysierten Call-Stack zur Verfügung, so dass Sie mit all diesen Informationen wirklich schöne Dinge tun können !

    
sehe 21.04.2011 08:55
quelle
1
  

Bevor es Code generiert, muss es prüfen, ob es bereits existiert

Es gibt ein paar Fälle, in denen das Abfangen einer Ausnahme -weise billiger ist, als zu verhindern, dass sie generiert wird. Dies ist ein Paradebeispiel. Sie können die IL für den Methodenkörper abrufen, aber Reflection ist kein Disassembler. Noch ist ein Disassembler eine echte Lösung, Sie müssten den gesamten Aufrufbaum zerlegen, um Ihr gewünschtes Verhalten zu implementieren. Schließlich könnte ein Methodenaufruf im Körper selbst eine Methode aufrufen, und so weiter. Es ist einfach einfacher, die Ausnahme zu erfassen, die der Jitter beim Kompilieren der IL auslöst.

    
Hans Passant 21.04.2011 09:12
quelle
0

Man kann die StackTrace-Klasse verwenden:

%Vor%

Die 1 kann angepasst werden und bestimmt die Anzahl der Frames, an denen Sie interessiert sind.

    
user492238 21.04.2011 08:19
quelle

Tags und Links