.net 如何获取调用方法的名称?
类的Log方法可以知道是谁调用它吗.net 如何获取调用方法的名称?,.net,.net,类的Log方法可以知道是谁调用它吗 class A { public void Log(string msg) { Log.Write("method_name: " + msg); } } 我想知道类的名称和方法的名称。您可以随时使用和类。您可以通过调用StrackTrace构造函数获取整个堆栈跟踪,也可以使用StackFrame构造函数获取特定的堆栈帧,该构造函数获取要跳过的帧数 您应该知道,由于内联,它可能不准确。(例如,方法A内联调用您的方法的方
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:是的,这是有道理的。如果代码调用失败或警告是内联的,它仍然会导致问题:)这么多好的答案,谢谢大家!