.net 如何获取调用方法的名称?

.net 如何获取调用方法的名称?,.net,.net,类的Log方法可以知道是谁调用它吗 class A { public void Log(string msg) { Log.Write("method_name: " + msg); } } 我想知道类的名称和方法的名称。您可以随时使用和类。您可以通过调用StrackTrace构造函数获取整个堆栈跟踪,也可以使用StackFrame构造函数获取特定的堆栈帧,该构造函数获取要跳过的帧数 您应该知道,由于内联,它可能不准确。(例如,方法A内联调用您的方法的方

类的Log方法可以知道是谁调用它吗

class A
{
    public void Log(string msg)
    {
        Log.Write("method_name: " + msg);
    }
}
我想知道类的名称和方法的名称。

您可以随时使用和类。您可以通过调用
StrackTrace
构造函数获取整个堆栈跟踪,也可以使用
StackFrame
构造函数获取特定的堆栈帧,该构造函数获取要跳过的帧数

您应该知道,由于内联,它可能不准确。(例如,方法A内联调用您的方法的方法B-将报告方法A,而不是方法B)

示例代码:

using System;
using System.Diagnostics;

class Test
{
    static void ShowCaller()
    {
        // Use this code if you want multiple frames
        // StackTrace trace = new StackTrace();
        // StackFrame frame = trace.GetFrame(1);

        // Use this code if you're only interested in one frame
        StackFrame frame = new StackFrame(1);
        Console.WriteLine(frame.GetMethod());
    }

    static void Intermediate()
    {
        ShowCaller();
    }

    static void Main()
    {
        Intermediate();
    }
}
作为优化的发布版本运行时,这将打印
Void Main()
——当运行调试版本时,或者如果您将更多代码放入
Intermediate()
方法中,它将打印
Void Intermediate()


(如注释中所述,这也会产生性能影响。您应该测量它,看看它在您的特定情况下是否可以接受。)

是的,它可以-通过创建一个新的
StackTrace
对象,然后使用
StackTrace.GetFrame(1).GetMethod().Name
-但是,这可能是一个昂贵的操作,因此,请测试并检查它是否不会导致应用程序过度减速。

您也可以尝试:

 class staitc A
    {
        public staitc  void Log(string msg)
        {
            Log.Write("method_name: " + msg);
        }
    }


        using System.Reflection;

class TestClass
{
       // in method

        private void TestMethod()
    {
           A.Log(MethodBase.GetCurrentMethod().Name +MethodBase.GetCurrentMethod().DeclaringType.FullName);
    }
}

从.NET 4.5开始,您可以通过
CallerMemberNameAttribute
获取调用方信息,它是
System.Runtime.CompilerServices
命名空间的一部分:

using System.Runtime.CompilerServices;

class A
{
    public void Log(string msg, [CallerMemberName] string memberName = "")
    {
        Log.Write("{0}: {1}", memberName, msg);
    }
}

+1:这确实是最好的方法,但一定要注意对性能的影响。我不知道它到底有多坏,但是如果你想在发布版本中运行,尤其是如果你调用“代码>日志<代码>,Lo.Log.Read最有可能不便宜,那么我的评论Re:可能是早熟……也许不是
Log.Write
应该尽可能便宜,因为您希望它也可以用于无错误日志记录。实现这一点的通常方法是让它尽快返回,将日志条目放入由单个线程编写的队列中(可能优先级较低)。我看到一个日志方法故意标记为“无内联”,正是出于这个原因。但是,正如你所说,这会带来很大的开销,所以我不建议这样做。(具体来说,我是指[MethodImpl(MethodImplOptions.NoInLine)]。@Steven:但在这种情况下,不是日志记录方法,而是调用日志记录方法的方法。@Jon:对不起,我不清楚。我看到的代码有一个私有的
Log
方法,该方法使用公共方法来记录特定严重性代码,例如
Fail
Warn
,等等。这些公共方法具有noinline属性,因此
Log
可以在调试或发布时查看两个调用者。我希望这能澄清问题。@Steve:是的,这是有道理的。如果代码调用失败或警告是内联的,它仍然会导致问题:)这么多好的答案,谢谢大家!