EnumExt.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Collections.Specialized;
  5. using System.ComponentModel;
  6. using System.ComponentModel.DataAnnotations;
  7. using System.Linq;
  8. using System.Reflection;
  9. namespace Masuit.Tools.Systems;
  10. /// <summary>
  11. /// 枚举扩展类
  12. /// </summary>
  13. public static partial class EnumExt
  14. {
  15. private static readonly ConcurrentDictionary<Type, Dictionary<int, string>> EnumNameValueDict = new();
  16. private static NullableDictionary<string, Type> _enumTypeDict;
  17. /// <summary>
  18. /// 获取枚举对象Key与显示名称的字典
  19. /// </summary>
  20. /// <param name="enumType"></param>
  21. /// <returns></returns>
  22. public static Dictionary<int, string> GetDictionary(this Type enumType)
  23. {
  24. if (!enumType.IsEnum)
  25. {
  26. throw new Exception("给定的类型不是枚举类型");
  27. }
  28. return EnumNameValueDict.GetOrAdd(enumType, _ => GetDictionaryItems(enumType));
  29. }
  30. private static Dictionary<int, string> GetDictionaryItems(Type enumType)
  31. {
  32. var enumItems = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
  33. var names = new Dictionary<int, string>(enumItems.Length);
  34. foreach (var enumItem in enumItems)
  35. {
  36. names[(int)enumItem.GetValue(enumType)] = enumItem.Name;
  37. }
  38. return names;
  39. }
  40. /// <summary>
  41. /// 获取枚举类型
  42. /// </summary>
  43. /// <param name="assembly"></param>
  44. /// <param name="typeName"></param>
  45. /// <returns></returns>
  46. public static Type GetEnumType(this Assembly assembly, string typeName)
  47. {
  48. _enumTypeDict ??= LoadEnumTypeDict(assembly);
  49. return _enumTypeDict[typeName];
  50. }
  51. /// <summary>
  52. /// 根据枚举成员获取Display的属性Name
  53. /// </summary>
  54. /// <returns></returns>
  55. public static string GetDisplay(this Enum en)
  56. {
  57. var type = en.GetType(); //获取类型
  58. var memberInfos = type.GetMember(en.ToString()); //获取成员
  59. if (memberInfos.Any() && memberInfos[0].GetCustomAttributes(typeof(DisplayAttribute), false) is DisplayAttribute[] attrs && attrs.Length > 0)
  60. {
  61. return attrs[0].Name; //返回当前描述
  62. }
  63. return en.ToString();
  64. }
  65. private static NullableDictionary<string, Type> LoadEnumTypeDict(Assembly assembly)
  66. {
  67. return assembly.GetTypes().Where(o => o.IsEnum).ToDictionarySafety(o => o.Name, o => o);
  68. }
  69. /// <summary>
  70. /// 获取枚举值的Description信息
  71. /// </summary>
  72. /// <param name ="value">枚举值</param>
  73. /// <param name ="args">要格式化的对象</param>
  74. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  75. public static string GetDescription(this Enum value, params object[] args)
  76. {
  77. var type = value.GetType();
  78. if (!Enum.IsDefined(type, value))
  79. {
  80. return Enum.GetValues(type).OfType<Enum>().Where(value.HasFlag).Select(e =>
  81. {
  82. var member = type.GetField(e.ToString());
  83. var description = member.GetCustomAttributes(typeof(DescriptionAttribute), false) is DescriptionAttribute[] attrs && attrs.Length != 0 ? attrs[0].Description : e.ToString();
  84. return args.Length > 0 ? string.Format(description, args) : description;
  85. }).Join(",");
  86. }
  87. var member = type.GetField(value.ToString());
  88. var description = member.GetCustomAttributes(typeof(DescriptionAttribute), false) is DescriptionAttribute[] attributes && attributes.Length != 0 ? attributes[0].Description : value.ToString();
  89. return args.Length > 0 ? string.Format(description, args) : description;
  90. }
  91. /// <summary>
  92. /// 获取枚举值的Description信息
  93. /// </summary>
  94. /// <param name ="value">枚举值</param>
  95. /// <param name ="args">要格式化的对象</param>
  96. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  97. public static IEnumerable<TAttribute> GetAttributes<TAttribute>(this Enum value) where TAttribute : Attribute
  98. {
  99. var type = value.GetType();
  100. if (!Enum.IsDefined(type, value))
  101. {
  102. return Enum.GetValues(type).OfType<Enum>().Where(value.HasFlag).SelectMany(e => type.GetField(e.ToString()).GetCustomAttributes<TAttribute>(false));
  103. }
  104. return type.GetField(value.ToString()).GetCustomAttributes<TAttribute>(false);
  105. }
  106. /// <summary>
  107. /// 拆分枚举值
  108. /// </summary>
  109. /// <param name ="value">枚举值</param>
  110. public static IEnumerable<TEnum> Split<TEnum>(this TEnum value) where TEnum : Enum
  111. {
  112. var type = typeof(TEnum);
  113. return Enum.IsDefined(type, value) ? new[]
  114. {
  115. value
  116. } : Enum.GetValues(type).Cast<TEnum>().Where(e => value.HasFlag(e));
  117. }
  118. /// <summary>
  119. /// 获取枚举值的Description信息
  120. /// </summary>
  121. /// <param name ="value">枚举值</param>
  122. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  123. public static EnumDescriptionAttribute GetEnumDescription(this Enum value)
  124. {
  125. return GetEnumDescriptions(value).FirstOrDefault();
  126. }
  127. /// <summary>
  128. /// 获取枚举值的Description信息
  129. /// </summary>
  130. /// <param name ="value">枚举值</param>
  131. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  132. public static NullableDictionary<string, (string Description, string Display)> GetTypedEnumDescriptions(this Enum value)
  133. {
  134. return GetEnumDescriptions(value).ToDictionarySafety(a => a.Language, a => (a.Description, a.Display));
  135. }
  136. /// <summary>
  137. /// 获取枚举值的Description信息
  138. /// </summary>
  139. /// <param name ="value">枚举值</param>
  140. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  141. public static IEnumerable<EnumDescriptionAttribute> GetEnumDescriptions(this Enum value)
  142. {
  143. if (value == null)
  144. {
  145. throw new ArgumentNullException(nameof(value));
  146. }
  147. var type = value.GetType();
  148. if (!Enum.IsDefined(type, value))
  149. {
  150. return Enum.GetValues(type).OfType<Enum>().Where(value.HasFlag).SelectMany(e => type.GetField(e.ToString()).GetCustomAttributes(typeof(EnumDescriptionAttribute), false).OfType<EnumDescriptionAttribute>());
  151. }
  152. return type.GetField(value.ToString()).GetCustomAttributes(typeof(EnumDescriptionAttribute), false).OfType<EnumDescriptionAttribute>();
  153. }
  154. /// <summary>
  155. /// 扩展方法:根据枚举值得到相应的枚举定义字符串
  156. /// </summary>
  157. /// <param name="value"></param>
  158. /// <param name="enumType"></param>
  159. /// <returns></returns>
  160. public static String ToEnumString(this int value, Type enumType)
  161. {
  162. return GetEnumStringFromEnumValue(enumType)[value.ToString()];
  163. }
  164. /// <summary>
  165. /// 根据枚举类型得到其所有的 值 与 枚举定义字符串 的集合
  166. /// </summary>
  167. /// <param name="enumType"></param>
  168. /// <returns></returns>
  169. public static NameValueCollection GetEnumStringFromEnumValue(Type enumType)
  170. {
  171. var nvc = new NameValueCollection();
  172. var fields = enumType.GetFields();
  173. foreach (FieldInfo field in fields)
  174. {
  175. if (field.FieldType.IsEnum)
  176. {
  177. var strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString();
  178. nvc.Add(strValue, field.Name);
  179. }
  180. }
  181. return nvc;
  182. }
  183. /// <summary>
  184. /// 根据枚举成员获取自定义属性EnumDisplayNameAttribute的属性DisplayName
  185. /// </summary>
  186. public static Dictionary<string, int> GetDescriptionAndValue(this Type enumType) => Enum.GetValues(enumType).Cast<object>().ToDictionary(e => (e as Enum).GetDescription(), e => (int)e);
  187. }