Wie der Titel schon sagt: Kann Reflection Ihnen den Namen der aktuell ausgeführten Methode geben?
Ich neige dazu, wegen des Heisenberg-Problems nicht zu raten. Wie rufen Sie eine Methode auf, die Ihnen die aktuelle Methode anzeigt, ohne die aktuelle Methode zu ändern? Aber ich hoffe, jemand kann mir dort das Gegenteil beweisen.
Aktualisieren:
- Teil 2: Könnte dies verwendet werden, um auch im Code nach einer Eigenschaft zu suchen?
- Teil 3: Wie würde die Aufführung aussehen?
Endergebnis
Ich habe von MethodBase.GetCurrentMethod () erfahren. Ich habe auch gelernt, dass ich nicht nur einen Stack-Trace erstellen kann, sondern nur den genauen Frame erstellen kann, den ich benötige, wenn ich möchte.
Um dies in einer Eigenschaft zu verwenden, nehmen Sie einfach eine .Substring (4), um 'set_' oder 'get_' zu entfernen.
.net
reflection
Joel Coehoorn
quelle
quelle
Antworten:
Ab .NET 4.5 können Sie auch [CallerMemberName] verwenden.
Beispiel: ein Eigenschaftssetzer (um Teil 2 zu beantworten):
Der Compiler stellt auf Callsites übereinstimmende String-Literale bereit, sodass im Grunde kein Leistungsaufwand entsteht.
quelle
StackFrame(1)
in anderen Antworten beschriebene Methode für die Protokollierung, die zu funktionieren schien, bis der Jitter beschloss, mit dem Inlining zu beginnen. Ich wollte das Attribut nicht hinzufügen, um Inlining aus Leistungsgründen zu verhindern. Mit dem[CallerMemberName]
Ansatz wurde das Problem behoben. Vielen Dank!OnPropertyChanged("SomeProperty")
und nichtOnPropertyChanged("SetProperty")
Für Nicht-
async
Methoden kann man verwendenhttps://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.getcurrentmethod
Bitte denken Sie daran, dass für
async
Methoden "MoveNext" zurückgegeben wird.quelle
async
Methode erhalten Sie höchstwahrscheinlich "MoveNext" als Methodennamen.Das von Lex bereitgestellte Snippet war etwas lang, daher weise ich auf den wichtigen Teil hin, da sonst niemand genau dieselbe Technik verwendete:
Dies sollte identische Ergebnisse für die MethodBase.GetCurrentMethod (). Name- Technik zurückgeben, aber es lohnt sich immer noch darauf hinzuweisen, da ich dies einmal in einer eigenen Methode implementieren könnte, indem ich Index 1 für die vorherige Methode verwende und es aus einer Reihe verschiedener Eigenschaften aufrufe. Außerdem wird nur ein Frame und nicht der gesamte Stack-Trace zurückgegeben:
Es ist auch ein Einzeiler;)
quelle
Versuchen Sie dies innerhalb der Main-Methode in einem leeren Konsolenprogramm:
Konsolenausgabe:
Main
quelle
Ja definitiv.
Wenn Sie möchten, dass ein Objekt manipuliert wird, verwende ich tatsächlich eine Funktion wie die folgende:
Diese Linie:
Geht den Stapelrahmen hoch, um die aufrufende Methode zu finden, und verwendet dann Reflection, um Parameterinformationswerte zu erhalten, die für eine generische Fehlerberichterstattungsfunktion an ihn übergeben wurden. Um die aktuelle Methode zu erhalten, verwenden Sie stattdessen einfach den aktuellen Stapelrahmen (1).
Wie andere für den aktuellen Methodennamen gesagt haben, können Sie auch Folgendes verwenden:
Ich gehe lieber über den Stapel, weil bei interner Betrachtung dieser Methode ohnehin einfach ein StackCrawlMark erstellt wird. Die direkte Adressierung des Stapels erscheint mir klarer
Nach 4.5 können Sie jetzt das [CallerMemberNameAttribute] als Teil der Methodenparameter verwenden, um eine Zeichenfolge des Methodennamens abzurufen. Dies kann in einigen Szenarien hilfreich sein (im obigen Beispiel jedoch wirklich).
Dies schien hauptsächlich eine Lösung für die INotifyPropertyChanged-Unterstützung zu sein, bei der zuvor Zeichenfolgen im gesamten Ereigniscode verstreut waren.
quelle
Vergleichen von Möglichkeiten zum Abrufen des Methodennamens - Verwenden eines beliebigen Timing-Konstrukts in LinqPad:
CODE
ERGEBNISSE
Reflexion Reflexion
Stacktrace Stacktrace
inlineconstant inlineconstant
Konstante Konstante
expr e => e.expr ()
exprmember exprmember
Callermember Main
Beachten Sie, dass die Methoden
expr
undcallermember
nicht ganz "richtig" sind. Und dort sehen Sie eine Wiederholung eines verwandten Kommentars, dass die Reflexion ~ 15x schneller ist als die Stapelverfolgung.quelle
BEARBEITEN: MethodBase ist wahrscheinlich ein besserer Weg, um nur die Methode zu erhalten, in der Sie sich befinden (im Gegensatz zum gesamten aufrufenden Stack). Ich würde mir jedoch immer noch Sorgen um Inlining machen.
Sie können eine StackTrace innerhalb der Methode verwenden:
Und der Blick auf die Rahmen:
Beachten Sie jedoch, dass Sie sich nicht in der Methode befinden, von der Sie glauben, dass Sie sie sind, wenn die Methode inline ist. Sie können ein Attribut verwenden, um Inlining zu verhindern:
quelle
new StackTrace(true)
stattdessen verwenden würdennew StackTrace(false)
. Wenn Sie diestrue
auf setzen, versucht der Stack-Trace, den Dateinamen, die Zeilennummer usw. zu erfassen, wodurch dieser Aufruf möglicherweise langsamer wird. Ansonsten eine schöne AntwortDer einfache Weg ist:
Wenn die System.Reflection im using-Block enthalten ist:
quelle
Wie wäre es damit:
quelle
Ich denke, Sie sollten in der Lage sein, dies durch das Erstellen eines StackTrace zu erreichen . Oder, wie @ edg und @ Lars Mæhlum erwähnen, MethodBase. GetCurrentMethod ()
quelle
Versuche dies...
quelle
Ich habe das gerade mit einer einfachen statischen Klasse gemacht:
dann in deinem Code:
quelle
quelle