[.Net] 通过反射,给Enum加备注
今天和大家分享一个给Enum加备注的技巧,话不多说,先上一段代码:
- namespace TestReflector.Model.Entities
- {
- public class UserInfo
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public UserStatusEnum UserStatus { get; set; }
- }
- public enum UserStatusEnum
- {
- /// <summary>
- /// 待审核
- /// </summary>
- WaitAudit,
- /// <summary>
- /// 审核中
- /// </summary>
- Auditing,
- /// <summary>
- /// 已审核
- /// </summary>
- Audited
- }
- }
相信大家在项目中都遇到过这种情况吧,用户的状态只是一个枚举,但UI层确需要显示对应的提示信息(例如“待审核”)。
怎样将Enum转换为字符串,写个转换方法?No!!!
下面介绍一种插入元数据的方式来实现此功能,使代码易维护,又不会分散在各个地方:
1. 首先建立一个工具类:
- /// <summary>
- /// 枚举类型扩展方法类
- /// </summary>
- public static class EnumExtention
- {
- /// <summary>
- /// 获取枚举值的详细文本[Description]
- /// </summary>
- /// <param name="target"></param>
- /// <returns></returns>
- public static string GetDescription(this System.Enum target)
- {
- Type t = target.GetType();
- //获取字段信息
- System.Reflection.FieldInfo[] fieldInfos = t.GetFields();
- foreach (System.Reflection.FieldInfo info in fieldInfos)
- {
- //判断名称是否相等
- if (info.Name != target.ToString()) continue;
- #region 4.5
- ////反射出自定义属性
- //var dscript = info.GetCustomAttribute<DescriptionAttribute>(true);
- ////类型转换找到一个Description,用Description作为成员名称
- //if (dscript != null)
- // return dscript.Description;
- #endregion
- #region 3.5
- //反射出自定义属性
- foreach (Attribute attr in info.GetCustomAttributes(true))
- {
- //类型转换找到一个Description,用Description作为成员名称
- var dscript = attr as DescriptionAttribute;
- if (dscript != null)
- return dscript.Description;
- }
- #endregion
- }
- //如果没有检测到合适的注释,则用默认名称
- return target.ToString();
- }
- }
2.第二步,我们来修改原来的UserStatusEnum:
- public enum UserStatusEnum
- {
- /// <summary>
- /// 待审核
- /// </summary>
- [Description("待审核")]
- WaitAudit,
- /// <summary>
- /// 审核中
- /// </summary>
- [Description("审核中")]
- Auditing,
- /// <summary>
- /// 已审核
- /// </summary>
- [Description("已审核")]
- Audited
- }
不要忘记导入命名空间:
- using System.ComponentModel;
3. OK,准备工作已经做好了,使用方法如下:
- class Program
- {
- private static void Main(string[] args)
- {
- var userStatus = UserStatusEnum.Auditing;
- string strUserStatus = userStatus.GetDescription();
- Console.WriteLine(strUserStatus);
- Console.ReadKey();
- }
- }
4. 输出结果:
5. 到了现在已经可以告一段落了,我们的小工具已经实现了需要的功能。但反射的效率如何呢?
我可以告诉大家的是:效率不堪入目。。。
6. 优化效率:
反射的耗时操作在于搜索元数据,我们可以将搜索出的MethodInfo、FieldInfo缓存一下,以达到提升效率的目的。
下面是我优化过后的结果:
7.可以看出。优化过后的代码执行效率提升了10倍左右。好了,今天的文章分享到这里,希望可以给大家带来方便。
- /// <summary>
- /// 枚举类型扩展方法类
- /// </summary>
- public static class EnumExtention
- {
- private static readonly Dictionary<RuntimeTypeHandle, FieldInfo[]> CacheFieldInfo = new Dictionary<RuntimeTypeHandle, FieldInfo[]>();
- private static readonly Dictionary<string, DescriptionAttribute> CacheDescriptionAttr = new Dictionary<string, DescriptionAttribute>();
- /// <summary>
- /// 获取枚举值的详细文本[Description]
- /// </summary>
- /// <param name="target"></param>
- /// <returns></returns>
- public static string GetDescription(this System.Enum target)
- {
- Type t = target.GetType();
- var typeHandle = t.TypeHandle;
- string strTarget = Enum.GetName(t, target);
- //获取字段信息
- System.Reflection.FieldInfo[] arrFieldInfo;
- if (CacheFieldInfo.ContainsKey(typeHandle))
- {
- arrFieldInfo = CacheFieldInfo[typeHandle];
- }
- else
- {
- arrFieldInfo = t.GetFields();
- CacheFieldInfo[typeHandle] = arrFieldInfo;
- }
- for (int i = arrFieldInfo.Length - ; i >= ; i--)
- {
- var fieldInfo = arrFieldInfo[i];
- //判断名称是否相等
- if (fieldInfo.Name != strTarget) continue;
- #region 3.5
- //反射出自定义属性
- if (CacheDescriptionAttr.ContainsKey(strTarget))
- {
- var dscript = CacheDescriptionAttr[strTarget];
- return dscript.Description;
- }
- else
- {
- var arrAttr = fieldInfo.GetCustomAttributes(true);
- for (int j = arrAttr.Length - ; j >= ; j--)
- {
- var attr = arrAttr[j];
- //类型转换找到一个Description,用Description作为成员名称
- var dscript = attr as DescriptionAttribute;
- if (dscript != null)
- {
- CacheDescriptionAttr[strTarget] = dscript;
- return dscript.Description;
- }
- }
- }
- #endregion 3.5
- }
- //如果没有检测到合适的注释,则用默认名称
- return strTarget;
- }
- }
[.Net] 通过反射,给Enum加备注的更多相关文章
- 反射 类的加载 Schema DOM 解析方式和解析器 命名空间
Day15 反射 1.1 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. l 加载 就是指将class文件读入内存,并为之创建 ...
- Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)
需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现 反射的过程如下: 第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...
- JAVA反射机制--静态加载与动态加载
Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如pu ...
- C# 反射实现动态加载程序集
原文:https://blog.csdn.net/pengdayong77/article/details/47622235 在.Net 中,程序集(Assembly)中保存了元数据(MetaData ...
- 反射和动态加载bean 完成 通用servie
最近我们部门有个小项目,用来管理这个公司所有项目用到的代码表,例如国家代码.行政区划代码等.这个项目的功能其实很少,就是简单的修改.查询.新增和逻辑删除.但是为每张表都写一套增删改查的页面和一套ser ...
- C#实现反射调用动态加载的DLL文件中的方法
反射的作用:1. 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型 2. 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射.3. ...
- windows的磁盘操作之七——获取当前所有的物理磁盘号 加备注
windows的磁盘操作之七--获取当前所有的物理磁盘号 2011-07-28 17:47:56 标签:windows API DeviceIoControl 物理磁盘 驱动器号 原创作品,允许转载 ...
- 仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢?
原文:仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢? 平时我们获取一个程序集或者类型的 Attribute 是非常轻松 ...
- JavaEE基础(二十七)/反射、JDK新特性
1.反射(类的加载概述和加载时机) A:类的加载概述 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 加载 就是指将class文件读入 ...
随机推荐
- jQuery(window) 和 jQuery(document)的区别
jQuery(window).height()代表了当前可见区域的大小,而jQuery(document).height()则代表了整个文档的高度,可视具体情况使用
- 初学c# -- 学习笔记(六) winfrom组件圆角
刚好用到这个功能,看了好些例子.我就不明白,简单的一个事,一些文章里的代码写的那个长啊,还让人看么. 精简后,就其实一点,只要有paint事件的组件,都可画圆角,没有的外面套一个panel就行了. u ...
- jsp js action之间的传值
1.struts2 action如何向JSP的JS函数传值 action中定义变量public class TestAction extends ActionSupport implements Se ...
- 笔记002:javascript简介
1. HTML服务于内容 CSS服务于表现 Javascript服务于行为(一切东西的粘合剂) 2.javascript能运行多种宿主环境中(Web浏览器最普遍) 3.历史 1995 Netscape ...
- 重复数据分析的三个常用语法distinct, group by, partition by
由于数据经常会出现重复现象,数据去重是数据分析中常用操作之一,而distinct,group by, partition by三者都可以实现去重功能,实践中需要根据不同的场景需求来选取相应的语法. d ...
- (转)在MAC上查找和设置$JAVA_HOME
最近升级了MAC OS,装了JDK7 for mac,在这里下载JDK7 for mac,装完之后发现在默认的路径下找不到JDK7的HOME,如下所示: $ which java /usr/bin/j ...
- 一般html5 手机端头部需要
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- java程序故障排查脚本之——CPU占用高
root@ubuntu-B85M-D3H:~/tmp# cat java_Analy.sh #!/bin/bash T=`ps -mp $1 -o THREAD,tid,time|sort -k 2 ...
- C#实现简单的委托异步调用
delegate void textAsy(); static void Main(string[] args) { textAsy t = texts; AsyncCallback callBack ...
- 【如何快速的开发一个完整的iOS直播app】(原理篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的 ...