C# 获取枚举 Enum 变量值的 Description 属性

在C#中如何读取枚举值的描述属性?

在C#中,有时候我们需要读取枚举值的描述属性,也就是说这个枚举值代表了什么意思。比如本文中枚举值 Chinese ,我们希望知道它代表意思的说明(即“中文”)。

 

有下面的枚举:

1
2
3
4
5
6
public enum EnumLanugage
{
    [System.ComponentModel.Description("中文")]
    Chinese,
    English
}

 

我们要获取的就是 Chinese 中的说明文字“中文”。

1
2
3
4
5
6
7
8
9
public string GetEnumDescription(Enum enumValue)
{
    string str = enumValue.ToString();
    System.Reflection.FieldInfo field = enumValue.GetType().GetField(str);
    object[] objs = field.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false);
    if (objs == null || objs.Length == 0) return str;
    System.ComponentModel.DescriptionAttribute da = (System.ComponentModel.DescriptionAttribute)objs[0];
    return da.Description;
}

 

调用 GetEnumDescription(EnumLanguage.Chinese) 后 将返回“中文”,如果换成 EnumLanguage.English ,由于在 English 上没有定义 Description ,将直接返回枚举名称 English 。


 

有些时候,某个方法的返回值是个枚举类型,比如描述登录结果:

1 public enum LoginResult
2 {
3     Success,
4     WrongPassword,
5     UserNotExist,
6     Forbidden,
7     Unknown
8 }

当前段UI获取到登陆方法的返回结果时,就需要告诉用户登录是否成功、什么原因失败的。如果直接使用 ToString() 方式直接返回枚举变量的名称,显然不合适。通常的做法是使用各 switch 来转换,弊端是要写过多的代码;或者构造一个 string[] msg ,再根据 LoginResult 的 int 值来相应的取,弊端是类型的int值必须是连续的或者 string[] msg 的个数大于或等于 枚举类型的最大 int 值 ,一一对应起来也比较麻烦 。
 
在 枚举类型 Enum 中,不支持 DisplayNameAttribute,但支持 DescriptionAttribute ,所以要从 DescriptionAttribute 入手。写一个通用方法,取出 DescriptionAttribute 即可。当然,为了使用方便,我们使用 .NET 3.5+ 支持的 扩展方法来实现:

01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Text;
05 using System.ComponentModel;
06 using System.Reflection;
07   
08 namespace com.hetaoos.Utils.Extensions
09 {
10     public static class Extensions
11     {
12         /// <summary>
13         /// 获取枚举变量值的 Description 属性
14         /// </summary>
15         /// <param name="obj">枚举变量</param>
16         /// <returns>如果包含 Description 属性,则返回 Description 属性的值,否则返回枚举变量值的名称</returns>
17         public static string GetDescription(this object obj)
18         {
19             return GetDescription(obj, false);
20         }
21   
22         /// <summary>
23         /// 获取枚举变量值的 Description 属性
24         /// </summary>
25         /// <param name="obj">枚举变量</param>
26         /// <param name="isTop">是否改变为返回该类、枚举类型的头 Description 属性,而不是当前的属性或枚举变量值的 Description 属性</param>
27         /// <returns>如果包含 Description 属性,则返回 Description 属性的值,否则返回枚举变量值的名称</returns>
28         public static string GetDescription(this object obj, bool isTop)
29         {
30             if (obj == null)
31             {
32                 return string.Empty;
33             }
34             try
35             {
36                 Type _enumType = obj.GetType();
37                 DescriptionAttribute dna = null;
38                 if (isTop)
39                 {
40                     dna = (DescriptionAttribute)Attribute.GetCustomAttribute(_enumType, typeof(DescriptionAttribute));
41                 }
42                 else
43                 {
44                     FieldInfo fi = _enumType.GetField(Enum.GetName(_enumType, obj));
45                     dna = (DescriptionAttribute)Attribute.GetCustomAttribute(
46                        fi, typeof(DescriptionAttribute));
47                 }
48                 if (dna != null && string.IsNullOrEmpty(dna.Description) == false)
49                     return dna.Description;
50             }
51             catch
52             {
53             }
54             return obj.ToString();
55         }
56     }
57 }

使用方法很简单:

01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Windows.Forms;
05 using System.ComponentModel;
06 using com.hetaoos.Utils.Extensions;//这一句是必须的,否则无法使用扩展方法
07 using System.Diagnostics;
08   
09 namespace com.hetaoos
10 {
11     static class Program
12     {
13         /// <summary>
14         /// 应用程序的主入口点。
15         /// </summary>
16         [STAThread]
17         static void Main()
18         {
19             ProcessedDataResultType resultType = ProcessedDataResultType.BkgrdMap;
20             ProcessedDataWaringResult ret = new ProcessedDataWaringResult() { ResultType = ProcessedDataResultType.WaringResult };
21             Debug.Print("枚举类型的描述属性:{0}", resultType.GetDescription(true));
22             Debug.Print("单个枚举变量的描述属性:{0} --> {1}", resultType, resultType.GetDescription());
23             Debug.Print("类类型的描述属性:{0}", ret.GetDescription(true));
24             Debug.Print("类类型的属性的描述属性:{0} --> {1}  --> {2}", ret.ResultType, ret.ResultType.GetDescription(), ret.ResultType.GetDescription(true));
25         }
26   
27         /// <summary>
28         /// 处理结果类型
29         /// </summary>
30         //[TypeConverter(typeof(EnumDescConverter))]
31         [Description("处理后的数据类型")]
32         public enum ProcessedDataResultType : byte
33         {
34             [Description("背景地图")]
35             BkgrdMap,
36             [Description("检测结果")]
37             WaringResult
38         }
39   
40         [Description("报警结果")]
41         public class ProcessedDataWaringResult
42         {
43             [Description("结果类型")]
44             public ProcessedDataResultType ResultType { get; set; }
45         }
46     }
47 }

输出结果如下:

1 枚举类型的描述属性:处理后的数据类型
2 单个枚举变量的描述属性:BkgrdMap --> 背景地图
3 类类型的描述属性:报警结果
4 类类型的属性的描述属性:WaringResult --> 检测结果  --> 处理后的数据类型

关联文章:

posted @ 2010-10-30 10:59  肚肚  阅读(2998)  评论(0编辑  收藏  举报