如何从代码中获取当前方法的名称

时间:2010-04-16 11:24:09

标签: c# introspection

我知道你可以做到

this.GetType().FullName

获得

My.Current.Class

但是我可以打电话来获取

My.Current.Class.CurrentMethod

8 个答案:

答案 0 :(得分:472)

从方法中调用System.Reflection.MethodBase.GetCurrentMethod().Name

答案 1 :(得分:323)

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的信用。

答案 2 :(得分:92)

反射有躲避森林树木的诀窍。您可以准确,快速地获取当前方法名称时遇到问题:

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] attribute让编译器在字符串参数中自动生成调用方法的名称。其他有用的属性是[CallerFilePath]让编译器生成源代码文件路径,[CallerLineNumber]用于获取进行调用的语句的源代码文件中的行号。


Update2:我在答案顶部提出的语法现在可以在没有花哨的重构工具的情况下在C#版本6中工作:

string currentMethodName = nameof(MyMethod);

答案 3 :(得分:31)

我认为获得全名的最佳方式是:

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

或试试这个

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

答案 4 :(得分:10)

这不起作用吗?

System.Reflection.MethodBase.GetCurrentMethod()
  

返回表示当前正在执行的方法的MethodBase对象。

     

命名空间:System.Reflection

     

程序集:mscorlib(在mscorlib.dll中)

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

答案 5 :(得分:9)

您也可以使用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

答案 6 :(得分:5)

System.Reflection.MethodBase.GetCurrentMethod().Name不是一个很好的选择'因为它只显示方法名称而没有其他信息。

string MyMethod(string str)一样,上述属性只返回MyMethod,这几乎不够。

最好使用System.Reflection.MethodBase.GetCurrentMethod().ToString(),它将返回整个方法签名......

答案 7 :(得分:3)