【问题标题】:How to find the method name of the calling method from a method at runtime?如何在运行时从方法中找到调用方法的方法名称?
【发布时间】:2010-11-18 06:39:33
【问题描述】:

如何在运行时从方法中找到调用方法的方法名?

例如:

Class A
{
    M1()
    {
        B.M2();
    }
}

class B
{
    public static M2()
    {
        // I need some code here to find out the name of the method that
        // called this method, preferably the name of the declared type
        // of the calling method also.
    }
}

【问题讨论】:

  • 认为您需要实现这样的目标通常是应用程序设计存在缺陷的好兆头。最好回顾一下设计,看看是否可以先解决这个问题。但是,在这种情况下,这并不总是严格正确的。为什么需要这样做?
  • @Jon:我自己从来没有做过,虽然我已经接近了几次。当试图理解刚刚落在您盘子上的热气腾腾的一堆时,这可能是一种有用的技术。
  • 调试器知道怎么做——为什么其他人需要知道怎么做?

标签: .net reflection


【解决方案1】:

你可以试试:

using System.Diagnostics;

StackTrace stackTrace = new StackTrace();
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);

【讨论】:

  • 嘿weichsel 这个不错..!!从我这边+1..!!虽然这个线程有点旧但绝对有用..!! :)
  • 请注意,如果您在 Release 中编译,这可能不会给出相同的结果 - 因为如果可以的话,JIT 将内联/尾调用您的方法。
【解决方案2】:

我想你正在寻找:

using System.Diagnostics;

StackTrace stackTrace = new StackTrace();
stackTrace.GetFrame(1).GetMethod().Name;

【讨论】:

  • -1 重复投票较高的旧项目(并且在相同的基础上 -1d 问题)
  • @Ruben - 从来没有意识到有人发布答案的速度比你应该投反对票的速度更快!
  • 我理解,这不是人们第一次拒绝我的分析。如果答案没有赞成票,我不会反对。我知道这在减少荒谬的情况下是不一致的。 (另一个问题有更好的答案——我正在寻找一个涵盖 NoInlining 点和语法的答案)。 (我个人要么删除我创建的副本,要么编辑它们以使其变得不同和/或比其他答案更好 - 如果其他人在我之前涵盖了相同的领域,我很高兴有人指出和/或被否决)。
【解决方案3】:

检查 System.Diagnostics.Trace 类,但据我所知 - 使用它时性能价格

【讨论】:

    【解决方案4】:

    最好不要使用 StackFrame,因为存在一些 .NET 安全问题。如果代码不完全受信任,则表达式“new StackFrame()”将引发安全异常。

    要获取当前方法,请使用:

    MethodBase.GetCurrentMethod().Name

    关于调用方法,请参阅 Stack Overflow 问题Object creation, how to resolve "class-owner"?

    【讨论】:

    • 感谢 ALor,但我猜你没抓住重点。我不想要当前方法名,我需要调用当前方法的方法名。 :)
    • 我最近问了同样的问题 ;) StackFrame 有很多问题 - 如果调用方法被 JIT 内联,你会得到错误的结果;
    【解决方案5】:

    您可以通过显示调用堆栈来做到这一点,如下面的代码所示。这将找到整个调用堆栈,而不仅仅是调用方法。

    void displaycallstack() {
        byte[] b;
        StackFrame sf;
        MemoryStream ms = new MemoryStream();
        String s = Process.GetCurrentProcess().ProcessName;
        Console.Out.WriteLine(s + " Call Stack");
        StackTrace st = new StackTrace();
        for (int a = 0;a < st.FrameCount; a++) {
            sf = st.GetFrame(a);
            s = sf.ToString();
            b = Encoding.ASCII.GetBytes(s);
            ms.Write(b,0,b.Length); 
        }
        ms.WriteTo(System.Console.OpenStandardOutput());
    }
    

    【讨论】:

    • 哇,这可能是我见过的任何人写控制台最有趣的方式 :-)
    • Jorn,在仔细查看了代码之后......我不得不同意。它只是取自一个关于如何显示堆栈跟踪的示例。下次我必须找到更好的例子:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 2013-07-07
    • 2011-06-06
    • 1970-01-01
    • 2010-11-27
    相关资源
    最近更新 更多