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


当前回答

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

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

其他回答

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

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/

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

    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 );
    }

您可以使用Caller Information和可选参数:

public static string WhoseThere([CallerMemberName] string memberName = "")
{
       return memberName;
}

这个测试说明了这一点:

[Test]
public void Should_get_name_of_calling_method()
{
    var methodName = CachingHelpers.WhoseThere();
    Assert.That(methodName, Is.EqualTo("Should_get_name_of_calling_method"));
}

虽然上面的StackTrace工作得相当快,在大多数情况下不会是一个性能问题,但调用者信息仍然要快得多。在1000次迭代的样本中,我发现它快了40倍。

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

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