.NET 中获取调用方法名
在写记录日志功能时,需要记录日志调用方所在的模块名、命名空间名、类名以及方法名,想到使用的是反射(涉及到反射请注意性能),但具体是哪一块儿还不了解,于是搜索,整理如下:
需要添加相应的命名空间:
using System;
using System.Diagnostics;
using System.Reflection;
如果仅是获取当前方法名使用 MethodBase.GetCurrentMethod 方法(返回表示当前正在执行的方法的 MethodBase 对象),可以使用如下代码:
public static void WriteSysLog(int level, string content)
{
MethodBase mb = MethodBase.GetCurrentMethod();
string systemModule = Environment.NewLine;
systemModule += "模块名:" + mb.Module.ToString() + Environment.NewLine;
systemModule += "命名空间名:" + mb.ReflectedType.Namespace + Environment.NewLine;
//完全限定名,包括命名空间
systemModule += "类名:" + mb.ReflectedType.FullName + Environment.NewLine;
systemModule += "方法名:" + mb.Name; Console.WriteLine("LogDate: {0}{1}Level: {2}{1}systemModule: {3}{1}content: {4}", DateTime.Now, Environment.NewLine, level, systemModule, content);
Console.WriteLine();
}
本文地址:http://www.cnblogs.com/Interkey/p/GetMethodName.html
但一般情况下是获取此记录日志方法的调用方,因此需要使用下面的代码:(此方法仅为演示)
public static void WriteSysLog(string content)
{
const int level = ; StackTrace ss = new StackTrace(true);
//index:0为本身的方法;1为调用方法;2为其上上层,依次类推
MethodBase mb = ss.GetFrame().GetMethod(); //本文地址:http://www.cnblogs.com/Interkey/p/GetMethodName.html
StackFrame[] sfs = ss.GetFrames();
string systemModule = Environment.NewLine;
systemModule += "模块名:" + mb.Module.ToString() + Environment.NewLine;
systemModule += "命名空间名:" + mb.DeclaringType.Namespace + Environment.NewLine;
//仅有类名
systemModule += "类名:" + mb.DeclaringType.Name + Environment.NewLine;
systemModule += "方法名:" + mb.Name; Console.WriteLine("LogDate: {0}{1}Level: {2}{1}systemModule: {3}{1}content: {4}", DateTime.Now, Environment.NewLine, level, systemModule, content);
Console.WriteLine();
}
对于这一点儿,感觉有意思的是Main的调用方,System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)。
通过
StackTrace ss = new StackTrace(true);
StackFrame[] sfs = ss.GetFrames();
可以得知.NET程序的执行顺序:
- System.Threading.ThreadHelper.ThreadStart()
- System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
- Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
- System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
然后进入方法Main中。
StackFrame指的是一个.net运行的时候堆栈上的一个帧(Frame),每次进入一个方法的时候就会有一个新的方法帧压入线程执行堆栈,可以通过StackFrame获取相关的信息,比如当前代码所在文件名和行号。
拓展方法是在.NET Framework 3.5以上版本才支持的,需要组件System.Core。
相关类:
- 在System.Diagnostics 命名空间中的 StackTrace 类 ,表示一个堆栈跟踪,它是一个或多个堆栈帧的有序集合。
- 在System.Diagnostics 命名空间中的 StackFrame 类 ,提供关于 StackFrame(表示当前线程的调用堆栈中的一个函数调用)的信息。
- 在System.Reflection 命名空间中的 MethodBase 类 ,提供有关方法和构造函数的信息。
另外,从 MethodBase 类 还可以获取很多其他属性,可以自行定位到System.Reflection.MethodBase 查看。
使用反射可以遍历获得类的所有属性名,方法名,成员名,其中一个有趣的小例子:通过反射将变量值转为变量名本身
文件:GetCurrentMethodName.zip [VS版本为2013,本例仅为演示]
后续:
感谢博友的提醒,使用CallerMemberNameAttribute 也可以实现获取调用方法名。示例请参考:调用方信息(C# 和 Visual Basic)。
C# 5.0 给我们带来了三个非常有用的编译器特性:CallerMemberNameAttribute、CallerFilePathAttribute、CallerLineNumberAttribute (在System.Runtime.CompilerServices 命名空间中),但这三个Attribute 是定义.NET Framework 4.5里的。
如果在低于.NET4.5中使用需要定义这些特性:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public class CallerMemberNameAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public class CallerFilePathAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public class CallerLineNumberAttribute : Attribute { }
}
关于 Attribute 和 AttributeUsageAttribute 的使用可自行搜索,有些偏题了…
参考:
- Logging method name in .NET
- c# 获取命名空间 类名 方法名
- 得到当前正在运行的方法或属性名[C#]
- C#如何获取被调用的方法的名称及参数列表?
- 获得当前程序的 空间名.类名.方法名
- C#获得调用方法的名称和类名
- 浅析StackTrace
- C# 5.0 CallerMemberName CallerFilePath CallerLineNumber 在.NET4中的使用
.NET 中获取调用方法名的更多相关文章
- 在IE中,JS方法名和input的name重名时,调用该方法无效
在IE中,JS方法名和input的name重名时,调用该方法无效.提示:网页错误详细信息 用户代理: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1 ...
- delphi中获取调用堆栈信息
异常堆栈有利于分析程序的错误,Delphi的Exception有StackTrace属性,但是值为空,因为StackTrace的信息收集Delphi委托给了第三方组件来完成,真是脑子有毛病! 借助于m ...
- Java中返回类型方法名
继承父类,子类含有两个分别为boy.Girl类名. 返回是需要返回方法 则返回变量名Person class Person { void eat() {} void speak() {} } clas ...
- JAVA中获取当前运行的类名,方法名,行数
JAVA中获取当前运行的类名,方法名,行数 public static String getTraceInfo(){ StringBuffer sb = new StringBuffer(); Sta ...
- C# 5.0中使用CallerMemberName、CallerFilePath和CallerLineNumber获取代码的调用方信息(转载)
很多时候,我们需要在运行过程中记录一些调测的日志信息,如下所示: public void DoProcessing() { TraceMessage("DoProcessing()被XXX调 ...
- Java中获取运行代码的类名、方法名
以下是案例,已运行通过 package com.hdys; /* * 1.获取当前运行代码的类名,方法名,主要是通过java.lang.StackTraceElement类 * * 2. * [1]获 ...
- ThinkPHP 3.2 中获取所有函数方法名,以及注释,完整可运行
<?php namespace Home\Controller; use Common\Controller\BaseController; class AuthController exten ...
- js中获取方法名
var tmp = arguments.callee.toString(); var re = /function\s*(\w*)/i; var matches = re.exec(tmp);//方法 ...
- [No000085]C#反射Demo,通过类名(String)创建类实例,通过方法名(String)调用方法
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy ...
随机推荐
- 【管理心得之三十八】如果“Q”不是高富帅,也吸引不了白富美“A”
场景再现=========================={美剧片段}一位老人在电话亭中,一次又一次地向公用电话投硬币,但是每一次仅是接通后就自动掉线了.老人无奈之下寻求他人拨打报修电话,但苦等了许 ...
- 常用 sql
一. sql 多个字段拼接 mysql: 1. concat函数 如果连接串中存在NULL,则返回结果为NULL: 例如: select concat('1','2','3') ...
- ASP.NET MVC 微信公众号支付,微信公众平台配置
微信公众号支付,首先要登录微信公众号进行配置: 第一步:配置网页授权域名
- angularjs定义全局变量
angularjs定义全局变量 三种方法 直接外层定义全局变量 利用ng的value定义全局变量 利用ng的constant定义全局变量 Takl is cheap, Show me the code ...
- python2与python3在windows下共存
python有python2(工业版)和python3,有时候我们会希望电脑上既有python2也有python3,!假设我们已经安装好,python2和python3了, 接下来我们找到python ...
- iOS苹果企业证书被撤销以及启用与管理
在国内, 积分墙以及各大助手(爱思助手, 91苹果助手, XY苹果助手, PP助手, 快用助手)等业务领域都在使用,苹果对证书的使用越来越严格.简单的分析一下,证书被封的原因. 一般证书被封会收到 ...
- 面向对象tab栏例子分析
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- KlayGE 4.4中渲染的改进(二):DR的其他改进
转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2749 上一篇讲了TBDR的实现,本篇继续讲解deferred rendering层的一些 ...
- PCurve - Curve on Surface
PCurve - Curve on Surface eryar@163.com Abstract. 本文通过给出曲面上曲线PCurve的定义来对OpenCascade中的Curve On Surfac ...
- 正则表达式之JSP、Android
对于正则表达式,很多朋友一定不陌生,因为在我们做网站或apk时,当需要用户提交表单时,很多时间需要判断用户的输入是否合法,这个时间正则表达式就可以发挥它的作用了,我们知道正则表达式在这个方面是很强大的 ...