当登录c#时,我如何才能知道调用当前方法的方法的名称?我知道所有关于System.Reflection.MethodBase.GetCurrentMethod(),但我想在堆栈跟踪中走一步。我考虑过解析堆栈跟踪,但我希望找到一种更清晰、更显式的方式,比如Assembly.GetCallingAssembly(),但用于方法。
当前回答
/// <summary>
/// Returns the call that occurred just before the "GetCallingMethod".
/// </summary>
public static string GetCallingMethod()
{
return GetCallingMethod("GetCallingMethod");
}
/// <summary>
/// Returns the call that occurred just before the the method specified.
/// </summary>
/// <param name="MethodAfter">The named method to see what happened just before it was called. (case sensitive)</param>
/// <returns>The method name.</returns>
public static string GetCallingMethod(string MethodAfter)
{
string str = "";
try
{
StackTrace st = new StackTrace();
StackFrame[] frames = st.GetFrames();
for (int i = 0; i < st.FrameCount - 1; i++)
{
if (frames[i].GetMethod().Name.Equals(MethodAfter))
{
if (!frames[i + 1].GetMethod().Name.Equals(MethodAfter)) // ignores overloaded methods.
{
str = frames[i + 1].GetMethod().ReflectedType.FullName + "." + frames[i + 1].GetMethod().Name;
break;
}
}
}
}
catch (Exception) { ; }
return str;
}
其他回答
显然这是一个迟来的答案,但如果你能使用。net 4.5或更新版本,我有一个更好的选择:
internal static void WriteInformation<T>(string text, [CallerMemberName]string method = "")
{
Console.WriteLine(DateTime.Now.ToString() + " => " + typeof(T).FullName + "." + method + ": " + text);
}
这将打印当前的日期和时间,后面跟着“Namespace.ClassName”。并以“:text”结尾。 样例输出:
6/17/2016 12:41:49 PM => WpfApplication.MainWindow..ctor: MainWindow initialized
示例使用:
Logger.WriteInformation<MainWindow>("MainWindow initialized");
从。net 4.5开始,你可以使用调用者信息属性:
CallerFilePath - The source file that called the function; CallerLineNumber - Line of code that called the function; CallerMemberName - Member that called the function. public void WriteLine( [CallerFilePath] string callerFilePath = "", [CallerLineNumber] long callerLineNumber = 0, [CallerMemberName] string callerMember= "") { Debug.WriteLine( "Caller File Path: {0}, Caller Line Number: {1}, Caller Member: {2}", callerFilePath, callerLineNumber, callerMember); }
这一设施也出现在“。NET Core"和"。净标准”。
参考文献
微软-呼叫者信息(c#) CallerFilePathAttribute类 CallerLineNumberAttribute类 CallerMemberNameAttribute类
我们可以对阿萨德先生的代码(目前公认的答案)稍加改进,只实例化我们实际需要的帧而不是整个堆栈:
new StackFrame(1).GetMethod().Name;
这可能会执行得更好一些,尽管在所有的可能性中,它仍然需要使用整个堆栈来创建单个帧。此外,它仍然有Alex Lyman指出的同样的警告(优化器/本机代码可能会破坏结果)。最后,你可能想要检查以确保新的StackFrame(1)或. getframe(1)不返回null,因为这种可能性看起来不太可能。
请看这个相关问题: 您可以使用反射来查找当前正在执行的方法的名称吗?
通常,您可以使用System.Diagnostics. stacktrace类来获取System.Diagnostics。然后使用GetMethod()方法获取System.Reflection.MethodBase对象。然而,这种方法有一些注意事项:
它表示运行时堆栈——优化可以内联一个方法,并且您不会在堆栈跟踪中看到该方法。 它不会显示任何本机帧,所以即使有机会您的方法被本机方法调用,这也将不起作用,而且实际上目前没有可用的方法来做到这一点。
(注:我只是在扩展Firas Assad提供的答案。)
注意,由于要进行优化,这样做在发布代码中是不可靠的。此外,在沙盒模式(网络共享)下运行应用程序根本不允许您获取堆栈帧。
考虑面向方面的编程(AOP),比如PostSharp,它不是从代码中调用,而是修改代码,从而始终知道它的位置。
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- 如何使用JSON确保字符串是有效的JSON。网
- 如何配置slf4j-simple
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- 如何在Python中记录源文件名称和行号
- c#和Java中的泛型有什么不同?和模板在c++ ?
- MongoDB记录所有查询