zoukankan      html  css  js  c++  java
  • [.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 UserStatusEnum
    13     {
    14         /// <summary>
    15         /// 待审核
    16         /// </summary>
    17         WaitAudit,
    18 
    19         /// <summary>
    20         /// 审核中
    21         /// </summary>
    22         Auditing,
    23 
    24         /// <summary>
    25         /// 已审核
    26         /// </summary>
    27         Audited
    28     }
    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.5
    22                 ////反射出自定义属性
    23                 //var dscript = info.GetCustomAttribute<DescriptionAttribute>(true);
    24                 ////类型转换找到一个Description,用Description作为成员名称
    25                 //if (dscript != null)
    26                 //    return dscript.Description; 
    27                 #endregion
    28 
    29                 #region 3.5
    30                 //反射出自定义属性
    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                 #endregion
    39             }
    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         Audited
    20     }

      不要忘记导入命名空间:

    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              else
    27              {
    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.5
    40  
    41                  //反射出自定义属性
    42                  if (CacheDescriptionAttr.ContainsKey(strTarget))
    43                  {
    44                      var dscript = CacheDescriptionAttr[strTarget];
    45                      return dscript.Description;
    46                  }
    47                  else
    48                  {
    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.5
    64              }
    65  
    66              //如果没有检测到合适的注释,则用默认名称
    67              return strTarget;
    68          }
    69      }
    View Code
  • 相关阅读:
    MySQL ——索引原理与慢查询优化(Day45)
    mysql 练习题(Day44)
    MySQL 多表查询(Day43)
    MySQL 单表查询(Day42)
    MySQL -表完整性约束(Day41)
    回调函数
    进程池
    共享数据, 信号量(了解),事件(了解)
    管道
    python并发编程之多进程
  • 原文地址:https://www.cnblogs.com/sweetWinne/p/4012135.html
Copyright © 2011-2022 走看看