今天和大家分享一个给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加备注的更多相关文章

  1. 反射 类的加载 Schema DOM 解析方式和解析器 命名空间

    Day15 反射 1.1 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. l 加载 就是指将class文件读入内存,并为之创建 ...

  2. Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)

    需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现   反射的过程如下:     第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...

  3. JAVA反射机制--静态加载与动态加载

    Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如pu ...

  4. C# 反射实现动态加载程序集

    原文:https://blog.csdn.net/pengdayong77/article/details/47622235 在.Net 中,程序集(Assembly)中保存了元数据(MetaData ...

  5. 反射和动态加载bean 完成 通用servie

    最近我们部门有个小项目,用来管理这个公司所有项目用到的代码表,例如国家代码.行政区划代码等.这个项目的功能其实很少,就是简单的修改.查询.新增和逻辑删除.但是为每张表都写一套增删改查的页面和一套ser ...

  6. C#实现反射调用动态加载的DLL文件中的方法

    反射的作用:1. 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型 2. 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射.3. ...

  7. windows的磁盘操作之七——获取当前所有的物理磁盘号 加备注

     windows的磁盘操作之七--获取当前所有的物理磁盘号 2011-07-28 17:47:56 标签:windows API DeviceIoControl 物理磁盘 驱动器号 原创作品,允许转载 ...

  8. 仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢?

    原文:仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢? 平时我们获取一个程序集或者类型的 Attribute 是非常轻松 ...

  9. JavaEE基础(二十七)/反射、JDK新特性

    1.反射(类的加载概述和加载时机) A:类的加载概述 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 加载  就是指将class文件读入 ...

随机推荐

  1. oracle常用命令大全及心得

    学习时整理的 Oracle 1.set linesize 100; 设置长度2.set pagesize 30; 设置每页显示数目3.em a.sql 打开记事本 4.@ a 执行文件a中的代码,可指 ...

  2. 注解式开发spring定时器

    1:spring 配置文件中增加这句    <task:annotation-driven/>  2:确保扫描程序能够扫描后  下面第3步骤的java类    <context:co ...

  3. Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结

    最近老是遇见服务器内存溢出的问题,故在网上搜了搜,总结了一些java内存溢出的解决方式 java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都 ...

  4. laravel(二):laravel基本入门 看到Hello Laravel

    1.Hello World 首先,我们来添加一些文字,在页面中显示.为了能访问网页,要启动程序服务器. $ php artisan serve 上述命令会启动 PHP 内建的开发服务器,要查看程序,请 ...

  5. maxiang.io css

    /**设置你自己的CSS.例如:h1 { border-bottom: 1px solid #ccc; line-height:1.6;}body { background:#FDFFD0} **/p ...

  6. JSON Object(如NSDictionary,NSArray)转化为JSON格式的NSString #iOS开发

    NSString *string = [self jsonObjectToJSONString:inputDataDic]; -(NSString*)jsonObjectToJSONString:(i ...

  7. jQuery实现折叠下拉效果

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. sql一对多的两个表的update

    scie_apprecord仪器表   和   scie_apporder仪器预约时间表 ,一个仪器可以有多条预约时间. 仪器表: 预约时间表: 需求: 由于一个仪器有好多条预约记录,将预约时间表的最 ...

  9. C# 闭包

    1. 首先要说明的是, delegate 被编译器 编译成一个class, 所以才能传来传去(具体参考 <CLR via C#>第四版), 所以 Action.Func也是如此 2. 在C ...

  10. MVC5+EF6 简易版CMS(非接口) 第四章:使用业务层方法,以及关联表解决方案

    目录 简易版CMS后台管理系统开发流程 MVC5+EF6 简易版CMS(非接口) 第一章:新建项目 MVC5+EF6 简易版CMS(非接口) 第二章:建数据模型 MVC5+EF6 简易版CMS(非接口 ...