EnumHelper.cs枚举助手(枚举描述信息多语言支持)C#
C#里面经常会用到枚举类型,枚举是值类型对象,如果你想用枚举类型的多属性特性,或者你想在MVC页面上通过简单的值类型转换,将某字段值所代表的含义转换为文字显示,这时候必须要将枚举扩展,是它支持文本描述属性,或者显示名称属性,亦或者多语言支持。例如同一个值类型的字段值,你想让它显示中文描述,英文描述……
请看下面的扩展示例:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Reflection; 5 using System.Collections.Concurrent; 6 using System.ComponentModel; 7 using System.Web.Mvc; 8 using System.Collections.Specialized; 9 10 namespace ZCPT.CrowdFunding.Web.Extension 11 { 12 /// <summary> 13 /// 枚举助手 14 /// 熊学浩 15 /// </summary> 16 public static class EnumHelper 17 { 18 #region Field 19 20 private static ConcurrentDictionary<Type, Dictionary<int, string>> enumDisplayValueDict = new ConcurrentDictionary<Type, Dictionary<int, string>>(); 21 private static ConcurrentDictionary<Type, Dictionary<string, int>> enumValueDisplayDict = new ConcurrentDictionary<Type, Dictionary<string, int>>(); 22 private static ConcurrentDictionary<Type, Dictionary<int, string>> enumNameValueDict = new ConcurrentDictionary<Type, Dictionary<int, string>>(); 23 private static ConcurrentDictionary<Type, Dictionary<string, int>> enumValueNameDict = new ConcurrentDictionary<Type, Dictionary<string, int>>(); 24 25 private static ConcurrentDictionary<Type, Dictionary<int, Tuple<string, int>>> enumSeqDisplayValueDict = new ConcurrentDictionary<Type, Dictionary<int, Tuple<string, int>>>(); 26 private static ConcurrentDictionary<string, Type> enumTypeDict = null; 27 28 #endregion 29 30 #region Method 31 /// <summary> 32 /// 获取枚举对象Key与显示名称的字典 33 /// </summary> 34 /// <param name="enumType"></param> 35 /// <returns></returns> 36 public static Dictionary<int, string> GetEnumDictionary(Type enumType) 37 { 38 if (!enumType.IsEnum) 39 throw new Exception("给定的类型不是枚举类型"); 40 41 Dictionary<int, string> names = enumNameValueDict.ContainsKey(enumType) ? enumNameValueDict[enumType] : new Dictionary<int, string>(); 42 43 if (names.Count == 0) 44 { 45 names = GetEnumDictionaryItems(enumType); 46 enumNameValueDict[enumType] = names; 47 } 48 return names; 49 } 50 51 private static Dictionary<int, string> GetEnumDictionaryItems(Type enumType) 52 { 53 FieldInfo[] enumItems = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); 54 Dictionary<int, string> names = new Dictionary<int, string>(enumItems.Length); 55 56 foreach (FieldInfo enumItem in enumItems) 57 { 58 int intValue = (int)enumItem.GetValue(enumType); 59 names[intValue] = enumItem.Name; 60 } 61 return names; 62 } 63 64 /// <summary> 65 /// 获取枚举对象显示名称与Key的字典 66 /// </summary> 67 /// <param name="enumType"></param> 68 /// <returns></returns> 69 public static Dictionary<string, int> GetEnumValueNameItems(Type enumType) 70 { 71 if (!enumType.IsEnum) 72 throw new Exception("给定的类型不是枚举类型"); 73 74 Dictionary<string, int> values = enumValueNameDict.ContainsKey(enumType) ? enumValueNameDict[enumType] : new Dictionary<string, int>(); 75 76 if (values.Count == 0) 77 { 78 values = TryToGetEnumValueNameItems(enumType); 79 enumValueNameDict[enumType] = values; 80 } 81 return values; 82 } 83 84 private static Dictionary<string, int> TryToGetEnumValueNameItems(Type enumType) 85 { 86 FieldInfo[] enumItems = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); 87 Dictionary<string, int> values = new Dictionary<string, int>(enumItems.Length); 88 89 foreach (FieldInfo enumItem in enumItems) 90 { 91 int intValue = (int)enumItem.GetValue(enumType); 92 values[enumItem.Name] = intValue; 93 } 94 return values; 95 } 96 97 98 /// <summary> 99 /// 获取枚举对象的值内容 100 /// </summary> 101 /// <param name="enumType"></param> 102 /// <param name="display"></param> 103 /// <returns></returns> 104 public static int TryToGetEnumValueByName(this Type enumType, string name) 105 { 106 if (!enumType.IsEnum) 107 throw new Exception("给定的类型不是枚举类型"); 108 Dictionary<string, int> enumDict = GetEnumValueNameItems(enumType); 109 return enumDict.ContainsKey(name) ? enumDict[name] : enumDict.Select(d => d.Value).FirstOrDefault(); 110 } 111 112 /// <summary> 113 /// 获取枚举类型 114 /// </summary> 115 /// <param name="assembly"></param> 116 /// <param name="typeName"></param> 117 /// <returns></returns> 118 public static Type TrytoGetEnumType(Assembly assembly, string typeName) 119 { 120 enumTypeDict = enumTypeDict ?? LoadEnumTypeDict(assembly); 121 if (enumTypeDict.ContainsKey(typeName)) 122 { 123 return enumTypeDict[typeName]; 124 } 125 return null; 126 } 127 128 private static ConcurrentDictionary<string, Type> LoadEnumTypeDict(Assembly assembly) 129 { 130 Type[] typeArray = assembly.GetTypes(); 131 Dictionary<string, Type> dict = typeArray.Where(o => o.IsEnum).ToDictionary(o => o.Name, o => o); 132 ConcurrentDictionary<string, Type> enumTypeDict = new ConcurrentDictionary<string, Type>(dict); 133 return enumTypeDict; 134 } 135 136 #endregion 137 /// <summary> 138 /// 枚举显示名(属性扩展) 139 /// </summary> 140 public class EnumDisplayNameAttribute : Attribute 141 { 142 private string _displayName; 143 144 public EnumDisplayNameAttribute(string displayName) 145 { 146 this._displayName = displayName; 147 } 148 149 public string DisplayName 150 { 151 get { return _displayName; } 152 } 153 } 154 155 public class EnumExt 156 { 157 /// <summary> 158 /// 根据枚举成员获取自定义属性EnumDisplayNameAttribute的属性DisplayName 159 /// </summary> 160 /// <param name="o"></param> 161 /// <returns></returns> 162 public static string GetEnumDisplayName(object o) 163 { 164 //获取枚举的Type类型对象 165 Type t = o.GetType(); 166 167 //获取枚举的所有字段 168 FieldInfo[] ms = t.GetFields(); 169 170 //遍历所有枚举的所有字段 171 foreach (FieldInfo f in ms) 172 { 173 if (f.Name != o.ToString()) 174 { 175 continue; 176 } 177 178 //第二个参数true表示查找EnumDisplayNameAttribute的继承链 179 if (f.IsDefined(typeof(EnumDisplayNameAttribute), true)) 180 { 181 return 182 (f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), true)[0] as EnumDisplayNameAttribute) 183 .DisplayName; 184 } 185 } 186 187 //如果没有找到自定义属性,直接返回属性项的名称 188 return o.ToString(); 189 } 190 191 /// <summary> 192 /// 根据枚举转换成SelectList 193 /// </summary> 194 /// <param name="enumType">枚举</param> 195 /// <returns></returns> 196 public static List<SelectListItem> GetSelectList(Type enumType) 197 { 198 List<SelectListItem> selectList = new List<SelectListItem>(); 199 foreach (object e in Enum.GetValues(enumType)) 200 { 201 selectList.Add(new SelectListItem() { Text = GetDescription(e), Value = ((int)e).ToString() }); 202 } 203 return selectList; 204 } 205 } 206 207 /// <summary> 208 /// 根据枚举转换成SelectList并且设置默认选中项 209 /// </summary> 210 /// <param name="enumType"></param> 211 /// <param name="ObjDefaultValue">默认选中项</param> 212 /// <returns></returns> 213 public static List<SelectListItem> GetSelectList(Type enumType, object ObjDefaultValue) 214 { 215 int defaultValue = Int32.Parse(ObjDefaultValue.ToString()); 216 List<SelectListItem> selectList = new List<SelectListItem>(); 217 foreach (object e in Enum.GetValues(enumType)) 218 { 219 try 220 { 221 if ((int)e == defaultValue) 222 { 223 selectList.Add(new SelectListItem() { Text = GetDescription(e), Value = ((int)e).ToString(), Selected = true }); 224 } 225 else 226 { 227 selectList.Add(new SelectListItem() { Text = GetDescription(e), Value = ((int)e).ToString() }); 228 } 229 } 230 catch (Exception ex) 231 { 232 string exs = ex.Message; 233 } 234 } 235 return selectList; 236 } 237 238 /// <summary> 239 /// 根据枚举转换成SelectList 240 /// </summary> 241 /// <param name="enumType">枚举</param> 242 /// <returns></returns> 243 public static List<SelectListItem> GetSelectList(Type enumType) 244 { 245 List<SelectListItem> selectList = new List<SelectListItem>(); 246 foreach (object e in Enum.GetValues(enumType)) 247 { 248 selectList.Add(new SelectListItem() { Text = GetDescription(e), Value = ((int)e).ToString() }); 249 } 250 return selectList; 251 } 252 /// <summary> 253 /// 根据枚举成员获取自定义属性EnumDisplayNameAttribute的属性DisplayName 254 /// </summary> 255 /// <param name="objEnumType"></param> 256 /// <returns></returns> 257 public static Dictionary<string, int> GetDescriptionAndValue(Type enumType) 258 { 259 Dictionary<string, int> dicResult = new Dictionary<string, int>(); 260 261 foreach (object e in Enum.GetValues(enumType)) 262 { 263 dicResult.Add(GetDescription(e), (int)e); 264 } 265 266 return dicResult; 267 } 268 269 /// <summary> 270 /// 根据枚举成员获取DescriptionAttribute的属性Description 271 /// </summary> 272 /// <param name="o"></param> 273 /// <returns></returns> 274 public static string GetDescription(object o) 275 { 276 //获取枚举的Type类型对象 277 Type t = o.GetType(); 278 279 //获取枚举的所有字段 280 FieldInfo[] ms = t.GetFields(); 281 282 //遍历所有枚举的所有字段 283 foreach (FieldInfo f in ms) 284 { 285 if (f.Name != o.ToString()) 286 { 287 continue; 288 } 289 //// Description 290 // //第二个参数true表示查找EnumDisplayNameAttribute的继承链 291 // if (f.IsDefined(typeof(EnumDisplayNameAttribute), true)) 292 // { 293 // return 294 // (f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), true)[0] as EnumDisplayNameAttribute) 295 // .DisplayName; 296 // } 297 FieldInfo fi = o.GetType().GetField(o.ToString()); 298 try 299 { 300 var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 301 return (attributes != null && attributes.Length > 0) ? attributes[0].Description : o.ToString(); 302 } 303 catch 304 { 305 return "(Unknow)"; 306 } 307 } 308 309 //如果没有找到自定义属性,直接返回属性项的名称 310 return o.ToString(); 311 } 312 313 #region 新增扩展方法 314 315 /// <summary> 316 /// 扩展方法:根据枚举值得到相应的枚举定义字符串 317 /// </summary> 318 /// <param name="value"></param> 319 /// <param name="enumType"></param> 320 /// <returns></returns> 321 public static String ToEnumString(this int value, Type enumType) 322 { 323 NameValueCollection nvc = GetEnumStringFromEnumValue(enumType); 324 return nvc[value.ToString()]; 325 } 326 327 /// <summary> 328 /// 根据枚举类型得到其所有的 值 与 枚举定义字符串 的集合 329 /// </summary> 330 /// <param name="enumType"></param> 331 /// <returns></returns> 332 public static NameValueCollection GetEnumStringFromEnumValue(Type enumType) 333 { 334 NameValueCollection nvc = new NameValueCollection(); 335 Type typeDescription = typeof(DescriptionAttribute); 336 System.Reflection.FieldInfo[] fields = enumType.GetFields(); 337 string strText = string.Empty; 338 string strValue = string.Empty; 339 foreach (FieldInfo field in fields) 340 { 341 if (field.FieldType.IsEnum) 342 { 343 strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString(); 344 nvc.Add(strValue, field.Name); 345 } 346 } 347 return nvc; 348 } 349 350 /// <summary> 351 /// 扩展方法:根据枚举值得到属性Description中的描述, 如果没有定义此属性则返回空串 352 /// </summary> 353 /// <param name="value"></param> 354 /// <param name="enumType"></param> 355 /// <returns></returns> 356 public static String ToEnumDescriptionString(this int value, Type enumType) 357 { 358 NameValueCollection nvc = GetNVCFromEnumValue(enumType); 359 return nvc[value.ToString()]; 360 } 361 362 /// <summary> 363 /// 根据枚举类型得到其所有的 值 与 枚举定义Description属性 的集合 364 /// </summary> 365 /// <param name="enumType"></param> 366 /// <returns></returns> 367 public static NameValueCollection GetNVCFromEnumValue(Type enumType) 368 { 369 NameValueCollection nvc = new NameValueCollection(); 370 Type typeDescription = typeof(DescriptionAttribute); 371 System.Reflection.FieldInfo[] fields = enumType.GetFields(); 372 string strText = string.Empty; 373 string strValue = string.Empty; 374 foreach (FieldInfo field in fields) 375 { 376 if (field.FieldType.IsEnum) 377 { 378 strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString(); 379 object[] arr = field.GetCustomAttributes(typeDescription, true); 380 if (arr.Length > 0) 381 { 382 DescriptionAttribute aa = (DescriptionAttribute)arr[0]; 383 strText = aa.Description; 384 } 385 else 386 { 387 strText = ""; 388 } 389 nvc.Add(strValue, strText); 390 } 391 } 392 return nvc; 393 } 394 395 #endregion 396 } 397 }