[.Net] 通过反射,给Enum加备注_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > [.Net] 通过反射,给Enum加备注

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

 2014/10/8 23:19:56  橡皮熊  程序员俱乐部  我要评论(0)
  • 摘要:今天和大家分享一个给Enum加备注的技巧,话不多说,先上一段代码:1namespaceTestReflector.Model.Entities2{3publicclassUserInfo4{5publicintId{get;set;}67publicstringName{get;set;}89publicUserStatusEnumUserStatus{get;set;}10}1112publicenumUserStatusEnum13{14///<summary>
  • 标签:

  今天和大家分享一个给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. 首先建立一个工具类:

     /// <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:

 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     }

 

上一篇: AES加密(兼容php,java,objective-c) 下一篇: 没有下一篇了!
  • 相关文章
发表评论
用户名: 匿名