今天和大家分享一个给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;
}
}

最新文章

  1. FragmentPagerAdapter+ViewPager+Fragment
  2. 清北学堂模拟day4 捡金币
  3. rman
  4. java语法糖3 深入剖析Java中的装箱和拆箱
  5. Non-constant Fields in Case Labels
  6. JDBC第一次学习
  7. Selenium2Library系列 keywords 之 _SelectElementKeywords 之 list_should_have_no_selections(self, locator)
  8. Linux Screen命令使用
  9. .net 控件开发第二天 怎么将 第一天写的代码 用到 .net中来
  10. socket计划——一个简单的例子
  11. Java IO流--练习2
  12. 迭代加深搜索 C++解题报告 :[SCOI2005]骑士精神
  13. Bootstrap知识记录:排版样式
  14. 【CF1042D】Petya and Array
  15. Lorem 占位符
  16. bzoj 4519: [Cqoi2016]不同的最小割 最小割树
  17. 【android】SDK在线升级
  18. Bash 快捷键[转]
  19. Xshell5 破解
  20. tcp/ip 调优示例

热门文章

  1. js中原型的概念
  2. C#连接Sql Serve数据库及增,删,改操作
  3. OAF 中的EO 和VO
  4. Java abstract class 和 interface 的区别
  5. &lt;![CDATA[ ]]&gt; 的作用
  6. C语言字符串拷贝
  7. R语言画全基因组关联分析中的曼哈顿图(manhattan plot)
  8. ajaxSubmit
  9. weblogic部署脚本
  10. Noip2016提高组 组合数问题problem