using System.Diagnostics;
...
var st = new StackTrace();
var sf = st.GetFrame(0);
var currentMethodName = sf.GetMethod();
Или, если вы хотите иметь вспомогательный метод:
[MethodImpl(MethodImplOptions.NoInlining)]
public string GetCurrentMethod()
{
var st = new StackTrace();
var sf = st.GetFrame(1);
return sf.GetMethod().Name;
}
Обновлено с благодарностями до @stusmith.
Вы также можете использовать MethodBase.GetCurrentMethod ()
, который запретит компилятору JIT встраивать метод, в котором он используется.
Обновление:
Этот метод содержит специальное перечисление StackCrawlMark
, которое, насколько я понимаю, укажет компилятору JIT, что текущий метод не должен быть встроен.
Это моя интерпретация комментария, связанного с этим перечислением, присутствующим в SSCLI. Далее следует комментарий:
// declaring a local var of this enum type and passing it by ref into a function
// that needs to do a stack crawl will both prevent inlining of the calle and
// pass an ESP point to stack crawl to
//
// Declaring these in EH clauses is illegal;
// they must declared in the main method body
Проверьте это: http://www.codeproject.com/KB/dotnet/MethodName.aspx
Reflection умеет скрывать лес за деревьями. У вас никогда не будет проблем с точным и быстрым получением текущего имени метода:
void MyMethod() {
string currentMethodName = "MyMethod";
//etc...
}
Хотя инструмент рефакторинга, вероятно, не исправит его автоматически.
Если вас совершенно не заботит (значительная) стоимость использования Reflection, то этот вспомогательный метод должен быть полезен:
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;
}
Обновление: C # версии 5 и .NET 4.5 предлагают золотое решение этой общей потребности, вы можете используйте атрибут [CallerMemberName] , чтобы компилятор автоматически генерировал имя вызывающего метода в строковом аргументе. Другие полезные атрибуты: [CallerFilePath], чтобы компилятор сгенерировал путь к файлу исходного кода, и [CallerLineNumber], чтобы получить номер строки в файле исходного кода для оператора, сделавшего вызов.
Update2: синтаксис, который я предложил в верхней части ответа, теперь можно заставить работать в C # версии 6 без изящного инструмента рефакторинга:
string currentMethodName = nameof(MyMethod);
Вызов System.Reflection.MethodBase.GetCurrentMethod (). Name
изнутри метода.