Как получить имя текущего метода из кода

Я знаю, что ты можешь сделать

this.GetType().FullName

Получить

My.Current.Class

Но что я могу позвонить, чтобы получить

My.Current.Class.CurrentMethod

8 ответов

Решение
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.

Вызов System.Reflection.MethodBase.GetCurrentMethod().Name изнутри метода.

У 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], чтобы получить номер строки в файле исходного кода для оператора, который сделал вызов.


Обновление 2: синтаксис, который я предложил в верхней части ответа, теперь можно заставить работать в C# версии 6 без причудливого инструмента рефакторинга:

string currentMethodName = nameof(MyMethod);

Я думаю, что лучший способ получить полное имя:

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

или попробуйте это

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

Это не работает?

System.Reflection.MethodBase.GetCurrentMethod()

Возвращает объект MethodBase, представляющий текущий выполняемый метод.

Пространство имен: System.Reflection

Сборка: mscorlib (в mscorlib.dll)

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

Вы также можете использовать 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

Что ж System.Reflection.MethodBase.GetCurrentMethod().Name не очень хороший выбор, потому что он просто отображает имя метода без дополнительной информации.

Как для string MyMethod(string str) вышеуказанное свойство вернет только MyMethod что вряд ли адекватно.

Лучше использовать System.Reflection.MethodBase.GetCurrentMethod().ToString() который вернет всю сигнатуру метода...

Другие вопросы по тегам