今天和大家分享一個給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 Code2.第二步,我們來修改原來的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新聞熱點
疑難解答