首页 > 代码库 > [.Net] 通过反射,给Enum加备注

[.Net] 通过反射,给Enum加备注

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

 

[.Net] 通过反射,给Enum加备注