德赢体育德赢体育

vwin德嬴手机客户端
德赢体育官网

c#利用反射实现对类中的常量进行取值和对应常量的注释

C#利用反射实现对类中的常量进行取值和对应常量的注释

因为业务需要,项目中有大量的错误码,还是通过分部类编写,报错之后返回一个错误码,无处可以方便的查询,后来发现代码中每个错误码都有定义,而且都还有注释,因此考虑通过反射实现读取然后格式化形成错误码文档方便参阅。

读取注释

首先先读取注释,注释只要是标准的///生成的就能读取,因为每个项目可以生成一个对应的xml注释文档,这个功能默认未开启,需要在要读取的类所在项目的名称上右键然后选择属性-生成-xml文档文件勾选上了并引入此项目,重新生成当前项目。这样在输出目录中就存在了xml文档了。

实现代码

首先代码不多,其次,代码中有详细注释,就不多说了,代码如下

这是需要解析的类示例:

/// <summary>/// 状态码类,存储状态码常量,这里的常量是http的状态码,用于反射解析/// </summary>public class StatusCode{ /// <summary> /// 客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。 /// </summary> public const int Continue = 100; /// <summary> /// 代表处理将被继续执行。 /// </summary> public const int Processing = 102; /// <summary> /// 请求已成功,请求所希望的响应头或数据体将随此响应返回。 /// </summary> public const int Ok = 200; /// <summary> /// 请求已经被实现,而且有一个新的资源已经依据请求的需要而创建,且其URI已经随Location头信息返回。 /// </summary> public const int Created = 201; /// <summary> /// 服务器已接受请求,但尚未处理。 /// </summary> public const int Accepted = 202;}

这是存储用的模型

/// 用于存储解析好的属性/// </summary>public class StatusCodeModel{ /// <summary> /// 状态码的全名 /// </summary> public string FullName { get; set; } /// <summary> /// 状态码的名称 /// </summary> public string Name { get; set; } /// <summary> /// 状态码的值 /// </summary> public int Value { get; set; } /// <summary> /// 状态码的注释 /// </summary> public string Note { get; set; }}

核心实现:

public void Test(){ //读取注释 //是从xx.xml文件里面读取,所以要确保要读取的类所在项目的属性-生成-xml文档文件勾选上了并引入此项目,重新生成当前项目 string filePath = Environment.CurrentDirectory + @"IceDog.DNL.CSharp.Grammar.xml"; XmlDocument xml = new XmlDocument(); //加载xml文件 xml.Load(filePath); //用于存储解析出来的xml注释 var dictNote = new Dictionary<string, string>(); //可以查看xml文档格式然后可以通过如下XPath表达式获取相关节点内容 var memebers = xml.SelectNodes("/doc/members/member"); foreach (object m in memebers) { //判断是否转换类型成功 if (m is XmlNode node) { //获取member节点的属性-名称 XmlAttribute propName = node.Attributes["name"]; string propNameValue = propName.Value; //里面还有一层summary节点,因为我们解析的是常量节点, //不会包含其他节点,所以不用进一步读取子节点 var value = node.InnerText.Trim(); //用于匹配的key var matchKey = "F:IceDog.DNL.CSharp.Grammar.Reflection.Constant.StatusCode."; //通过name值进行解析,目前发现的前缀有 F:field,M:method,T;type,P:property if (propNameValue.IndexOf(matchKey, StringComparison.Ordinal) > -1) { //去掉前缀和冒号,然后赋值 dictNote[propNameValue.Substring(2)] =value; } } } //解析常量对象 //存储解析的内容 var codeList = new List<StatusCodeModel>(); var constants = new ArrayList(); Type type = typeof(StatusCode); //从规定的约束内搜索字段 //约束有是静态成员,是公共成员,和返回父级的公共静态成员, FieldInfo[] infoList = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); foreach (FieldInfo info in infoList) { //按照要解析的字段的特性来判断, //常量是字面量,不可以在构造函数中初始化 if (info.IsLiteral && !info.IsInitOnly) { constants.Add(info); } } //常量信息列表 var constantInfoList = (FieldInfo[])constants.ToArray(typeof(FieldInfo)); foreach (FieldInfo info in constantInfoList) { var scm = new StatusCodeModel { Value = (int)info.GetRawConstantValue(), Name = info.Name, FullName = info.DeclaringType.FullName + "." + info.Name }; scm.Note = dictNote[scm.FullName]; codeList.Add(scm); } //通过值进行升序排序 codeList.Sort((m1, m2) => m1.Value - m2.Value); //接下来就可以进行自己需要的操作了, //这里是json序列化 var str = JsonConvert.SerializeObject(codeList); Console.WriteLine(str);}

输出结果如下

[{"FullName":"IceDog.DNL.CSharp.Grammar.Reflection.Constant.StatusCode.Continue","Name":"Continue","Value":100,"Note":"客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。"},{"FullName":"IceDog.DNL.CSharp.Grammar.Reflection.Constant.StatusCode.Processing","Name":"Processing","Value":102,"Note":"代表处理将被继续执行。"},{"FullName":"IceDog.DNL.CSharp.Grammar.Reflection.Constant.StatusCode.Ok","Name":"Ok","Value":200,"Note":"请求已成功,请求所希望的响应头或数据体将随此响应返回。"},{"FullName":"IceDog.DNL.CSharp.Grammar.Reflection.Constant.StatusCode.Created","Name":"Created","Value":201,"Note":"请求已经被实现,而且有一个新的资源已经依据请求的需要而创建,且其URI已经随Location头信息返回。"},{"FullName":"IceDog.DNL.CSharp.Grammar.Reflection.Constant.StatusCode.Accepted","Name":"Accepted","Value":202,"Note":"服务器已接受请求,但尚未处理。"}]

参考文档

Getting a list of constants using Reflection https://weblogs.asp.net/whaggard/2708请问如何通过反射机制获取一个类的常量值 https://social.msdn.microsoft.com/Forums/zh-CN/b39303fa-5f3d-4bef-ac5e-06e5ad095df2/35831383822291420309368903680721453235562642621046337192146219?forum=visualcshartzhchsXPath 语法 http://www.w3school.com.cn/xpath/xpath_syntax.aspBindingFlags 枚举 https://msdn.microsoft.com/zh-cn/library/cexkb29a

欢迎阅读本文章: 田智鹏

vwin德赢体育app

vwin德嬴手机客户端