503 Stimmen

Wie man den Namen der aktuellen Methode aus dem Code erhält

Ich weiß, dass du es kannst

this.GetType().FullName

Um die

My.Current.Class

Aber was kann ich anrufen, um die

My.Current.Class.CurrentMethod

11 Stimmen

this.ToString() gibt Ihnen den aktuellen Klassennamen nur, wenn Sie nichts Besonderes in Ihrem eigenen public override string ToString() . GetType().FullName gibt immer Ihren vollen Namen an.

0 Stimmen

@Pasi danke, werde meine Implementierung ändern

6 Stimmen

In .Net 4.5 können Sie das Attribut CallerMemberNameAttribute verwenden, um den Namen des Aufrufers zu erhalten. Siehe msdn.microsoft.com/de-us/library/ ... Sie können dann den Körper Ihrer Funktion in eine anonyme Funktion wie in ([CallerMemberName] string functionName = "")=>{ } verpacken. Die Probleme bei der Verwendung der Reflection-Methode wie in der akzeptierten Antwort bestehen darin, dass (1) die Funktion möglicherweise inlined wird und/oder (2) der Funktionsname verschleiert werden kann, wenn er nicht öffentlich ist und der Code verschleiert wird.

660voto

Jamie Ide Punkte 46985

Rufen Sie an. System.Reflection.MethodBase.GetCurrentMethod().Name innerhalb der Methode.

5 Stimmen

Leidet dies unter Inlining?

16 Stimmen

Wenn Sie sich fragen, was schneller ist, Reflection oder StackTrace, sehen Sie hier nach: stackoverflow.com/a/1348853/495455

157 Stimmen

Um Ihre Zeit zu sparen, gehen Sie auf den obigen Link: StackTrace ist schneller.

444voto

using System.Diagnostics;
...

var st = new StackTrace();
var sf = st.GetFrame(0);

var currentMethodName = sf.GetMethod();

Oder, wenn Sie eine Hilfsmethode wünschen:

[MethodImpl(MethodImplOptions.NoInlining)]
public string GetCurrentMethod()
{
    var st = new StackTrace();
    var sf = st.GetFrame(1);

    return sf.GetMethod().Name;
}

Aktualisiert mit Credits an @stusmith.

68 Stimmen

Denken Sie daran, dass das JIT frei ist, Methoden zu inlinen, was dies beeinträchtigen könnte. Um zu erzwingen, dass eine Methode nicht inline ist, fügen Sie das Attribut [MethodImpl(MethodImplOptions.NoInlining)] hinzu.

40 Stimmen

Beachten Sie, dass das Hinzufügen von MethodImpl(MethodImplOptions.NoInlining) à GetCurrentMethod verhindert nur, dass diese Methode in ihren Aufrufer eingefügt wird. Sie verhindert nicht, dass die aufrufende Methode selbst in ihren eigenen Aufrufer eingefügt wird usw. usw.

0 Stimmen

@Luke: Das ist natürlich möglich und verkompliziert die Dinge.

190voto

Hans Passant Punkte 894572

Seit C# Version 6 können Sie einfach aufrufen:

string currentMethodName = nameof(MyMethod);

In C# Version 5 und .NET 4.5 können Sie die Attribut [CallerMemberName] um den Compiler den Namen der aufrufenden Methode in einem String-Argument automatisch generieren zu lassen. Weitere nützliche Attribute sind [CallerFilePath], damit der Compiler den Pfad der Quellcodedatei generiert, und [CallerLineNumber], um die Zeilennummer in der Quellcodedatei für die Anweisung zu erhalten, die den Aufruf getätigt hat.


Davor gab es noch einige kompliziertere Methoden, um den Namen der Methode zu erhalten, die aber viel einfacher waren:

void MyMethod() {
  string currentMethodName = "MyMethod";
  //etc...
}

Allerdings wird ein Refactoring das Problem wahrscheinlich nicht automatisch beheben.

Wenn Ihnen die (beträchtlichen) Kosten für die Nutzung des Systems völlig egal sind Reflection dann sollte diese Hilfsmethode nützlich sein:

using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Reflection;
//...

[MethodImpl(MethodImplOptions.NoInlining)]
public static string GetMyMethodName() {
  var st = new StackTrace(new StackFrame(1));
  return st.GetFrame(0).GetMethod().Name;
}

0 Stimmen

Ich habe das schon einmal gemacht. Die Wartung kann mühsam sein, wenn man es anwendungsübergreifend macht, aber ansonsten: Einfach ist immer besser als clever!

3 Stimmen

Richtig ist, dass es etwa 10.000 Mal schneller ist, plus/minus einen Faktor von 10.

18 Stimmen

+1 für den [CallerMemberNameAttribute] .NET 4.5 Tipp. Danke.

49voto

Zakaria Punkte 995

Ich denke, der beste Weg, den vollständigen Namen zu erhalten, ist:

 this.GetType().FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;

oder versuchen Sie dies

string method = string.Format("{0}.{1}", MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name);

1 Stimmen

+1 weil die Verwendung von Reflexion um mehrere Größenordnungen schneller ist als die Verwendung von StackTrace.

25 Stimmen

Dies funktioniert nicht bei async Methoden. Ich nenne System.Reflection.MethodBase.GetCurrentMethod().Name in der ersten Zeile einer Methode und ich erhalte MoveNext .

1 Stimmen

Ist es möglich, eine Funktion zu erstellen, die die Funktionsklasse/den Funktionsnamen des Aufrufers zurückgibt? Ihre Lösung ist großartig, aber ein wenig lang, jedes Mal aufgerufen werden. Es wäre ideal, wenn dies auf einige andere Klasse und öffentliche Funktion oder vielleicht öffentliche Eigenschaft, die aufgerufen werden kann. Idealerweise in einer statischen Klasse.

13voto

Orwellophile Punkte 12151

Funktioniert das nicht?

System.Reflection.MethodBase.GetCurrentMethod()

Gibt ein MethodBase-Objekt zurück, das die aktuell ausgeführte Methode darstellt.

Namespace: System.Reflection

Baugruppe: mscorlib (in mscorlib.dll)

http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getcurrentmethod.aspx

2 Stimmen

Nicht für async Methoden

1 Stimmen

@Devnsyde für async Methoden, besuchen Sie bitte meine Antwort in stackoverflow.com/questions/44153/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X