今天和大家分享一个给Enum加备注的技巧,话不多说,先上一段代码:
1 namespace TestReflector.Model.Entities 2 { 3 public class UserInfo 4 { 5 public int Id { get; set; } 6 7 public string Name { get; set; } 8 9 public UserStatusEnum UserStatus { get; set; }10 }11 12 public enum UserStatusEnum13 {14 /// <summary>15 /// 待审核16 /// </summary>17 WaitAudit,18 19 /// <summary>20 /// 审核中21 /// </summary>22 Auditing,23 24 /// <summary>25 /// 已审核26 /// </summary>27 Audited28 }29 }
相信大家在项目中都遇到过这种情况吧,用户的状态只是一个枚举,但UI层确需要显示对应的提示信息(例如“待审核”)。
怎样将Enum转换为字符串,写个转换方法?No!!!
下面介绍一种插入元数据的方式来实现此功能,使代码易维护,又不会分散在各个地方:
1. 首先建立一个工具类:
1 /// <summary> 2 /// 枚举类型扩展方法类 3 /// </summary> 4 public static class EnumExtention 5 { 6 /// <summary> 7 /// 获取枚举值的详细文本[Description] 8 /// </summary> 9 /// <param name="target"></param>10 /// <returns></returns>11 public static string GetDescription(this System.Enum target)12 {13 Type t = target.GetType();14 //获取字段信息15 System.Reflection.FieldInfo[] fieldInfos = t.GetFields();16 foreach (System.Reflection.FieldInfo info in fieldInfos)17 {18 //判断名称是否相等19 if (info.Name != target.ToString()) continue;20 21 #region 4.522 ////反射出自定义属性23 //var dscript = info.GetCustomAttribute<DescriptionAttribute>(true);24 ////类型转换找到一个Description,用Description作为成员名称25 //if (dscript != null)26 // return dscript.Description; 27 #endregion28 29 #region 3.530 //反射出自定义属性31 foreach (Attribute attr in info.GetCustomAttributes(true))32 {33 //类型转换找到一个Description,用Description作为成员名称34 var dscript = attr as DescriptionAttribute;35 if (dscript != null)36 return dscript.Description;37 }38 #endregion39 }40 41 //如果没有检测到合适的注释,则用默认名称42 return target.ToString();43 }44 45 }View Code
2.第二步,我们来修改原来的UserStatusEnum:
1 public enum UserStatusEnum 2 { 3 /// <summary> 4 /// 待审核 5 /// </summary> 6 [Description("待审核")] 7 WaitAudit, 8 9 /// <summary>10 /// 审核中11 /// </summary>12 [Description("审核中")]13 Auditing,14 15 /// <summary>16 /// 已审核17 /// </summary>18 [Description("已审核")]19 Audited20 }
不要忘记导入命名空间:
using System.ComponentModel;
3. OK,准备工作已经做好了,使用方法如下:
1 class PRogram 2 { 3 private static void Main(string[] args) 4 { 5 var userStatus = UserStatusEnum.Auditing; 6 7 string strUserStatus = userStatus.GetDescription(); 8 9 Console.WriteLine(strUserStatus);10 11 Console.ReadKey();12 }13 }
4. 输出结果:
5. 到了现在已经可以告一段落了,我们的小工具已经实现了需要的功能。但反射的效率如何呢?
我可以告诉大家的是:效率不堪入目。。。
6. 优化效率:
反射的耗时操作在于搜索元数据,我们可以将搜索出的MethodInfo、FieldInfo缓存一下,以达到提升效率的目的。
下面是我优化过后的结果:
7.可以看出。优化过后的代码执行效率提升了10倍左右。好了,今天的文章分享到这里,希望可以给大家带来方便。
1 /// <summary> 2 /// 枚举类型扩展方法类 3 /// </summary> 4 public static class EnumExtention 5 { 6 private static readonly Dictionary<RuntimeTypeHandle, FieldInfo[]> CacheFieldInfo = new Dictionary<RuntimeTypeHandle, FieldInfo[]>(); 7 private static readonly Dictionary<string, DescriptionAttribute> CacheDescriptionAttr = new Dictionary<string, DescriptionAttribute>(); 8 9 /// <summary>10 /// 获取枚举值的详细文本[Description]11 /// </summary>12 /// <param name="target"></param>13 /// <returns></returns>14 public static string GetDescription(this System.Enum target)15 {16 Type t = target.GetType();17 var typeHandle = t.TypeHandle;18 string strTarget = Enum.GetName(t, target);19 20 //获取字段信息21 System.Reflection.FieldInfo[] arrFieldInfo;22 if (CacheFieldInfo.ContainsKey(typeHandle))23 {24 arrFieldInfo = CacheFieldInfo[typeHandle];25 }26 else27 {28 arrFieldInfo = t.GetFields();29 CacheFieldInfo[typeHandle] = arrFieldInfo;30 }31 32 for (int i = arrFieldInfo.Length - 1; i >= 0; i--)33 {34 var fieldInfo = arrFieldInfo[i];35 36 //判断名称是否相等37 if (fieldInfo.Name != strTarget) continue;38 39 #region 3.540 41 //反射出自定义属性42 if (CacheDescriptionAttr.ContainsKey(strTarget))43 {44 var dscript = CacheDescriptionAttr[strTarget];45 return dscript.Description;46 }47 else48 {49 var arrAttr = fieldInfo.GetCustomAttributes(true);50 for (int j = arrAttr.Length - 1; j >= 0; j--)51 {52 var attr = arrAttr[j];53 //类型转换找到一个Description,用Description作为成员名称54 var dscript = attr as DescriptionAttribute;55 if (dscript != null)56 {57 CacheDescriptionAttr[strTarget] = dscript;58 return dscript.Description;59 }60 }61 }62 63 #endregion 3.564 }65 66 //如果没有检测到合适的注释,则用默认名称67 return strTarget;68 }69 }View Code
新闻热点
疑难解答