在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 --> 检测结果 --> 处理后的数据类型 |
关联文章: