枚举的多语言显示 使用Attribute
还是jhh0111昨天关于枚举的双语显示问题的帖子的问题,有不少人跟贴询问使用Attribute的实现,于是刚才乘午间休息实现了一个,这里share一下。
主要框架还是和枚举的多语言显示里一样,对Enum包装了一个DataSource,唯一不同的是里面的每一个Item的DisplayValue采用从Attribute读出,所以这里就不再贴出EnumDataSource代码了(请参考枚举的多语言显示),这里仅仅列出和上篇不同的地方:
显然这里的静态方法是很重要的,通过它就可以访问枚举的额外信息了:
主要框架还是和枚举的多语言显示里一样,对Enum包装了一个DataSource,唯一不同的是里面的每一个Item的DisplayValue采用从Attribute读出,所以这里就不再贴出EnumDataSource代码了(请参考枚举的多语言显示),这里仅仅列出和上篇不同的地方:
1
public string DisplayValue
2
{
3
get
4
{
5
Dictionary<CultureInfo, EnumItemDescriptionAttribute> disc =
6
EnumItemDescriptionAttribute.GetDisplayValues(_value, typeof(EnumType));
7
CultureInfo currentUICulute = Thread.CurrentThread.CurrentUICulture;
8
if (disc.ContainsKey(currentUICulute))
9
return disc[currentUICulute].Description;
10
return _value.ToString();
11
}
12
}
这里取值是通过EnumItemDescriptionAttribute上的静态Helper方法提供,如果找到对应Culture的Attribute就应用,否则返回默认值(枚举的ToString)。
public string DisplayValue2
{3
get4
{5
Dictionary<CultureInfo, EnumItemDescriptionAttribute> disc =6
EnumItemDescriptionAttribute.GetDisplayValues(_value, typeof(EnumType));7
CultureInfo currentUICulute = Thread.CurrentThread.CurrentUICulture;8
if (disc.ContainsKey(currentUICulute))9
return disc[currentUICulute].Description;10
return _value.ToString();11
}12
}显然这里的静态方法是很重要的,通过它就可以访问枚举的额外信息了:
1
/// <summary>
2
/// Define the item of special enum used attribute, you can use it mulitple for multi-descript one enum item.
3
/// </summary>
4
[AttributeUsage(AttributeTargets.Field, AllowMultiple=true)]
5
public class EnumItemDescriptionAttribute : Attribute
6
{
7
/// <summary>
8
/// A cache store, because accessing Attribute is according to reflection, it cost too much
9
/// So I add a cache, which based on special enum Type.
10
/// </summary>
11
private static readonly Dictionary<Type, Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>> _cache =
12
new Dictionary<Type,Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>>();
13
/// <summary>
14
/// the culture of Description
15
/// </summary>
16
private CultureInfo _culture;
17
/// <summary>
18
/// the description content.
19
/// </summary>
20
private string _description;
21
22
/// <summary>
23
/// Constructor a new <see cref="EnumItemDescriptionAttribute"/> with special culture name and description.
24
/// </summary>
25
/// <param name="cultureName">the name of special culture, like en-US, zh-CN etc.</param>
26
/// <param name="description">the content of Descroption</param>
27
public EnumItemDescriptionAttribute(string cultureName, string description)
28
: this(CultureInfo.GetCultureInfo(cultureName), description)
29
{
30
}
31
32
/// <summary>
33
/// Constructor a new <see cref="EnumItemDescriptionAttribute"/> with special culture id and description.
34
/// </summary>
35
/// <param name="cultureId">the ID of special culture, like 1033 etc.</param>
36
/// <param name="description">the content of Descroption</param>
37
public EnumItemDescriptionAttribute(int cultureId, string description)
38
: this(CultureInfo.GetCultureInfo(cultureId), description)
39
{
40
}
41
42
/// <summary>
43
/// Internal constructor.
44
/// </summary>
45
/// <param name="culture">special <see cref="CultureInfo"/></param>
46
/// <param name="description">the content of Descroption</param>
47
private EnumItemDescriptionAttribute(CultureInfo culture, string description)
48
{
49
_culture = culture;
50
_description = description;
51
}
52
53
/// <summary>
54
/// Gets the <see cref="CultureInfo"/> for current decription.
55
/// </summary>
56
public CultureInfo Culture
57
{
58
get { return _culture; }
59
}
60
61
/// <summary>
62
/// Gets the description content.
63
/// </summary>
64
public string Description
65
{
66
get { return _description; }
67
}
68
69
/// <summary>
70
/// Gets all <see cref="EnumItemDescriptionAttribute"/>
71
/// for special enum value: <paramref name="value"/> and special enum type: <paramref name="enumType"/>.
72
/// </summary>
73
/// <param name="value">the value of special enum</param>
74
/// <param name="enumType">the enum type of special enum</param>
75
/// <returns>All attributes attatched on special enum value.</returns>
76
public static Dictionary<CultureInfo, EnumItemDescriptionAttribute> GetDisplayValues(object value, Type enumType)
77
{
78
if (enumType == null || !enumType.IsEnum)
79
{
80
throw new NotSupportedException("enumType is not a Enum");
81
}
82
if (value == null || !Enum.IsDefined(enumType, value))
83
{
84
throw new ArgumentException("value is not defined in " + enumType.FullName);
85
}
86
87
return GetDisplayValuesImp(value, enumType);
88
}
89
90
/// <summary>
91
/// Gets the <see cref="EnumItemDescriptionAttribute"/> for special enum value: <paramref name="value"/>,
92
/// special enum type: <paramref name="enumType"/> and special culture.
93
/// </summary>
94
/// <param name="value">the value of special enum</param>
95
/// <param name="enumType">the enum type of special enum</param>
96
/// <param name="culture">special culture for item description.</param>
97
/// <returns>The attributes attatched on special enum value.</returns>
98
public static string GetDisplayValue(object value, Type enumType, CultureInfo culture)
99
{
100
if (enumType == null || !enumType.IsEnum)
101
{
102
throw new NotSupportedException("enumType is not a Enum");
103
}
104
if (value == null || !Enum.IsDefined(enumType, value))
105
{
106
throw new ArgumentException("value is not defined in " + enumType.FullName);
107
}
108
109
if (culture == null)
110
return value.ToString();
111
112
Dictionary<CultureInfo, EnumItemDescriptionAttribute> disc = GetDisplayValuesImp(value, enumType);
113
if (disc.ContainsKey(culture))
114
return disc[culture].Description;
115
return value.ToString();
116
}
117
118
/// <summary>
119
/// Gets all <see cref="EnumItemDescriptionAttribute"/>
120
/// for special enum value: <paramref name="value"/> and special enum type: <paramref name="enumType"/>.
121
/// </summary>
122
/// <param name="value">the value of special enum</param>
123
/// <param name="enumType">the enum type of special enum</param>
124
/// <returns>All attributes attatched on special enum value.</returns>
125
private static Dictionary<CultureInfo, EnumItemDescriptionAttribute> GetDisplayValuesImp(object value, Type enumType)
126
{
127
if (!_cache.ContainsKey(enumType))
128
{
129
Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>> displayValues =
130
new Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>();
131
foreach (Enum item in Enum.GetValues(enumType))
132
{
133
Dictionary<CultureInfo, EnumItemDescriptionAttribute> descriptions =
134
new Dictionary<CultureInfo, EnumItemDescriptionAttribute>();
135
FieldInfo enumField = enumType.GetField(item.ToString());
136
if (enumField != null)
137
{
138
foreach (EnumItemDescriptionAttribute desc
139
in enumField.GetCustomAttributes(typeof(EnumItemDescriptionAttribute), true))
140
{
141
descriptions.Add(desc.Culture, desc);
142
}
143
}
144
displayValues.Add(item, descriptions);
145
}
146
_cache.Add(enumType, displayValues);
147
}
148
149
return _cache[enumType][value];
150
}
151
}
使用示例如下:
/// <summary>2
/// Define the item of special enum used attribute, you can use it mulitple for multi-descript one enum item.3
/// </summary>4
[AttributeUsage(AttributeTargets.Field, AllowMultiple=true)]5
public class EnumItemDescriptionAttribute : Attribute6
{7
/// <summary>8
/// A cache store, because accessing Attribute is according to reflection, it cost too much9
/// So I add a cache, which based on special enum Type.10
/// </summary>11
private static readonly Dictionary<Type, Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>> _cache = 12
new Dictionary<Type,Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>>();13
/// <summary>14
/// the culture of Description15
/// </summary>16
private CultureInfo _culture;17
/// <summary>18
/// the description content.19
/// </summary>20
private string _description;21

22
/// <summary>23
/// Constructor a new <see cref="EnumItemDescriptionAttribute"/> with special culture name and description.24
/// </summary>25
/// <param name="cultureName">the name of special culture, like en-US, zh-CN etc.</param>26
/// <param name="description">the content of Descroption</param>27
public EnumItemDescriptionAttribute(string cultureName, string description)28
: this(CultureInfo.GetCultureInfo(cultureName), description)29
{30
}31

32
/// <summary>33
/// Constructor a new <see cref="EnumItemDescriptionAttribute"/> with special culture id and description.34
/// </summary>35
/// <param name="cultureId">the ID of special culture, like 1033 etc.</param>36
/// <param name="description">the content of Descroption</param>37
public EnumItemDescriptionAttribute(int cultureId, string description)38
: this(CultureInfo.GetCultureInfo(cultureId), description)39
{40
}41

42
/// <summary>43
/// Internal constructor.44
/// </summary>45
/// <param name="culture">special <see cref="CultureInfo"/></param>46
/// <param name="description">the content of Descroption</param>47
private EnumItemDescriptionAttribute(CultureInfo culture, string description)48
{49
_culture = culture;50
_description = description;51
}52

53
/// <summary>54
/// Gets the <see cref="CultureInfo"/> for current decription.55
/// </summary>56
public CultureInfo Culture57
{58
get { return _culture; }59
}60

61
/// <summary>62
/// Gets the description content.63
/// </summary>64
public string Description65
{66
get { return _description; }67
}68

69
/// <summary>70
/// Gets all <see cref="EnumItemDescriptionAttribute"/>71
/// for special enum value: <paramref name="value"/> and special enum type: <paramref name="enumType"/>.72
/// </summary>73
/// <param name="value">the value of special enum</param>74
/// <param name="enumType">the enum type of special enum</param>75
/// <returns>All attributes attatched on special enum value.</returns>76
public static Dictionary<CultureInfo, EnumItemDescriptionAttribute> GetDisplayValues(object value, Type enumType)77
{78
if (enumType == null || !enumType.IsEnum)79
{80
throw new NotSupportedException("enumType is not a Enum");81
}82
if (value == null || !Enum.IsDefined(enumType, value))83
{84
throw new ArgumentException("value is not defined in " + enumType.FullName);85
}86

87
return GetDisplayValuesImp(value, enumType);88
}89

90
/// <summary>91
/// Gets the <see cref="EnumItemDescriptionAttribute"/> for special enum value: <paramref name="value"/>,92
/// special enum type: <paramref name="enumType"/> and special culture.93
/// </summary>94
/// <param name="value">the value of special enum</param>95
/// <param name="enumType">the enum type of special enum</param>96
/// <param name="culture">special culture for item description.</param>97
/// <returns>The attributes attatched on special enum value.</returns>98
public static string GetDisplayValue(object value, Type enumType, CultureInfo culture)99
{100
if (enumType == null || !enumType.IsEnum)101
{102
throw new NotSupportedException("enumType is not a Enum");103
}104
if (value == null || !Enum.IsDefined(enumType, value))105
{106
throw new ArgumentException("value is not defined in " + enumType.FullName);107
}108

109
if (culture == null)110
return value.ToString();111

112
Dictionary<CultureInfo, EnumItemDescriptionAttribute> disc = GetDisplayValuesImp(value, enumType);113
if (disc.ContainsKey(culture))114
return disc[culture].Description;115
return value.ToString();116
}117

118
/// <summary>119
/// Gets all <see cref="EnumItemDescriptionAttribute"/>120
/// for special enum value: <paramref name="value"/> and special enum type: <paramref name="enumType"/>.121
/// </summary>122
/// <param name="value">the value of special enum</param>123
/// <param name="enumType">the enum type of special enum</param>124
/// <returns>All attributes attatched on special enum value.</returns>125
private static Dictionary<CultureInfo, EnumItemDescriptionAttribute> GetDisplayValuesImp(object value, Type enumType)126
{127
if (!_cache.ContainsKey(enumType))128
{129
Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>> displayValues =130
new Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>();131
foreach (Enum item in Enum.GetValues(enumType))132
{133
Dictionary<CultureInfo, EnumItemDescriptionAttribute> descriptions =134
new Dictionary<CultureInfo, EnumItemDescriptionAttribute>();135
FieldInfo enumField = enumType.GetField(item.ToString());136
if (enumField != null)137
{138
foreach (EnumItemDescriptionAttribute desc139
in enumField.GetCustomAttributes(typeof(EnumItemDescriptionAttribute), true))140
{141
descriptions.Add(desc.Culture, desc);142
}143
}144
displayValues.Add(item, descriptions);145
}146
_cache.Add(enumType, displayValues);147
}148

149
return _cache[enumType][value];150
}151
} 1
private void Form1_Load(object sender, EventArgs e)
2
{
3
this.comboBox1.DataSource = new EnumDataSource2<Sex>();
4
this.comboBox1.DisplayMember = "DisplayValue";
5
this.comboBox1.ValueMember = "Value";
6
}
7
8
public enum Sex
9
{
10
[EnumItemDescription("zh-CN", "男")]
11
[EnumItemDescription("ja", "男性")]
12
[EnumItemDescription("de", "Männliche")]
13
Male,
14
[EnumItemDescription("zh-CN", "女")]
15
[EnumItemDescription("ja", "女性")]
16
[EnumItemDescription("de", "Weibliche")]
17
Female
18
}
private void Form1_Load(object sender, EventArgs e)2
{3
this.comboBox1.DataSource = new EnumDataSource2<Sex>();4
this.comboBox1.DisplayMember = "DisplayValue";5
this.comboBox1.ValueMember = "Value";6
}7

8
public enum Sex9
{10
[EnumItemDescription("zh-CN", "男")]11
[EnumItemDescription("ja", "男性")]12
[EnumItemDescription("de", "Männliche")]13
Male,14
[EnumItemDescription("zh-CN", "女")]15
[EnumItemDescription("ja", "女性")]16
[EnumItemDescription("de", "Weibliche")]17
Female18
}


浙公网安备 33010602011771号