当登录c#时,我如何才能知道调用当前方法的方法的名称?我知道所有关于System.Reflection.MethodBase.GetCurrentMethod(),但我想在堆栈跟踪中走一步。我考虑过解析堆栈跟踪,但我希望找到一种更清晰、更显式的方式,比如Assembly.GetCallingAssembly(),但用于方法。
当前回答
StackFrame caller = (new System.Diagnostics.StackTrace()).GetFrame(1);
string methodName = caller.GetMethod().Name;
我想这就够了。
其他回答
快速回顾一下这两种方法,速度比较是重要的部分。
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 实际上更快。
在c# 5中,你可以使用调用者信息来获取这些信息:
//using System.Runtime.CompilerServices;
public void SendError(string Message, [CallerMemberName] string callerName = "")
{
Console.WriteLine(callerName + "called me.");
}
也可以获取[CallerFilePath]和[CallerLineNumber]。
我使用的另一种方法是向所讨论的方法添加参数。例如,使用void Foo(string context)而不是void Foo()。然后传入一些表示调用上下文的惟一字符串。
如果您只需要调用者/上下文进行开发,您可以在发布之前删除参数。
额外信息给Firas Assaad回答。
我已经使用了新的StackFrame(1).GetMethod().Name;在.net核心2.1依赖注入和我得到调用方法为“开始”。
我尝试使用[System.Runtime.CompilerServices。CallerMemberName = "" 并给出了正确的调用方法
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/