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


当前回答

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/

其他回答

通常,您可以使用System.Diagnostics. stacktrace类来获取System.Diagnostics。然后使用GetMethod()方法获取System.Reflection.MethodBase对象。然而,这种方法有一些注意事项:

它表示运行时堆栈——优化可以内联一个方法,并且您不会在堆栈跟踪中看到该方法。 它不会显示任何本机帧,所以即使有机会您的方法被本机方法调用,这也将不起作用,而且实际上目前没有可用的方法来做到这一点。

(注:我只是在扩展Firas Assad提供的答案。)

快速回顾一下这两种方法,速度比较是重要的部分。

http://geekswithblogs.net/BlackRabbitCoder/archive/2013/07/25/c.net-little-wonders-getting-caller-information.aspx

在编译时确定调用者

static void Log(object message, 
[CallerMemberName] string memberName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
    // we'll just use a simple Console write for now    
    Console.WriteLine("{0}({1}):{2} - {3}", fileName, lineNumber, memberName, message);
}

使用堆栈确定调用者

static void Log(object message)
{
    // frame 1, true for source info
    StackFrame frame = new StackFrame(1, true);
    var method = frame.GetMethod();
    var fileName = frame.GetFileName();
    var lineNumber = frame.GetFileLineNumber();

    // we'll just use a simple Console write for now    
    Console.WriteLine("{0}({1}):{2} - {3}", fileName, lineNumber, method.Name, message);
}

两种方法的比较

Time for 1,000,000 iterations with Attributes: 196 ms
Time for 1,000,000 iterations with StackTrace: 5096 ms

因此,您可以看到,使用属性要快得多!近25 x 实际上更快。

试试这个:

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#]。

也许你正在寻找这样的东西:

StackFrame frame = new StackFrame(1);
frame.GetMethod().Name; //Gets the current method name

MethodBase method = frame.GetMethod();
method.DeclaringType.Name //Gets the current class name

注意,由于要进行优化,这样做在发布代码中是不可靠的。此外,在沙盒模式(网络共享)下运行应用程序根本不允许您获取堆栈帧。

考虑面向方面的编程(AOP),比如PostSharp,它不是从代码中调用,而是修改代码,从而始终知道它的位置。