当登录c#时,我如何才能知道调用当前方法的方法的名称?我知道所有关于System.Reflection.MethodBase.GetCurrentMethod(),但我想在堆栈跟踪中走一步。我考虑过解析堆栈跟踪,但我希望找到一种更清晰、更显式的方式,比如Assembly.GetCallingAssembly(),但用于方法。


当前回答

试试这个:

using System.Diagnostics;
// Get call stack
StackTrace stackTrace = new StackTrace(); 
// Get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);

一行程序:

(new System.Diagnostics.StackTrace()).GetFrame(1).GetMethod().Name

它来自Get调用方法使用反射[c#]。

其他回答

显然这是一个迟来的答案,但如果你能使用。net 4.5或更新版本,我有一个更好的选择:

internal static void WriteInformation<T>(string text, [CallerMemberName]string method = "")
{
    Console.WriteLine(DateTime.Now.ToString() + " => " + typeof(T).FullName + "." + method + ": " + text);
}

这将打印当前的日期和时间,后面跟着“Namespace.ClassName”。并以“:text”结尾。 样例输出:

6/17/2016 12:41:49 PM => WpfApplication.MainWindow..ctor: MainWindow initialized

示例使用:

Logger.WriteInformation<MainWindow>("MainWindow initialized");
/// <summary>
/// Returns the call that occurred just before the "GetCallingMethod".
/// </summary>
public static string GetCallingMethod()
{
   return GetCallingMethod("GetCallingMethod");
}

/// <summary>
/// Returns the call that occurred just before the the method specified.
/// </summary>
/// <param name="MethodAfter">The named method to see what happened just before it was called. (case sensitive)</param>
/// <returns>The method name.</returns>
public static string GetCallingMethod(string MethodAfter)
{
   string str = "";
   try
   {
      StackTrace st = new StackTrace();
      StackFrame[] frames = st.GetFrames();
      for (int i = 0; i < st.FrameCount - 1; i++)
      {
         if (frames[i].GetMethod().Name.Equals(MethodAfter))
         {
            if (!frames[i + 1].GetMethod().Name.Equals(MethodAfter)) // ignores overloaded methods.
            {
               str = frames[i + 1].GetMethod().ReflectedType.FullName + "." + frames[i + 1].GetMethod().Name;
               break;
            }
         }
      }
   }
   catch (Exception) { ; }
   return str;
}

要获得方法名和类名,请尝试以下方法:

    public static void Call()
    {
        StackTrace stackTrace = new StackTrace();

        var methodName = stackTrace.GetFrame(1).GetMethod();
        var className = methodName.DeclaringType.Name.ToString();

        Console.WriteLine(methodName.Name + "*****" + className );
    }

我们可以对阿萨德先生的代码(目前公认的答案)稍加改进,只实例化我们实际需要的帧而不是整个堆栈:

new StackFrame(1).GetMethod().Name;

这可能会执行得更好一些,尽管在所有的可能性中,它仍然需要使用整个堆栈来创建单个帧。此外,它仍然有Alex Lyman指出的同样的警告(优化器/本机代码可能会破坏结果)。最后,你可能想要检查以确保新的StackFrame(1)或. getframe(1)不返回null,因为这种可能性看起来不太可能。

请看这个相关问题: 您可以使用反射来查找当前正在执行的方法的名称吗?

private static MethodBase GetCallingMethod()
{
  return new StackFrame(2, false).GetMethod();
}

private static Type GetCallingType()
{
  return new StackFrame(2, false).GetMethod().DeclaringType;
}

这里有一个很棒的课程:http://www.csharp411.com/c-get-calling-method/