EnumExtension.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // 麻省理工学院许可证
  2. //
  3. // 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司 联系电话/微信:18020030720 QQ:515096995
  4. //
  5. // 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
  6. //
  7. // 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
  8. // 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
  9. namespace Admin.NET.Core;
  10. /// <summary>
  11. /// 枚举拓展
  12. /// </summary>
  13. public static class EnumExtension
  14. {
  15. // 枚举显示字典缓存
  16. private static readonly ConcurrentDictionary<Type, Dictionary<int, string>> EnumDisplayValueDict = new();
  17. // 枚举值字典缓存
  18. private static readonly ConcurrentDictionary<Type, Dictionary<int, string>> EnumNameValueDict = new();
  19. // 枚举类型缓存
  20. private static ConcurrentDictionary<string, Type> _enumTypeDict;
  21. /// <summary>
  22. /// 获取枚举对象Key与名称的字典(缓存)
  23. /// </summary>
  24. /// <param name="enumType"></param>
  25. /// <returns></returns>
  26. public static Dictionary<int, string> GetEnumDictionary(this Type enumType)
  27. {
  28. if (!enumType.IsEnum)
  29. throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
  30. // 查询缓存
  31. var enumDic = EnumNameValueDict.ContainsKey(enumType) ? EnumNameValueDict[enumType] : new Dictionary<int, string>();
  32. if (enumDic.Count != 0)
  33. return enumDic;
  34. // 取枚举类型的Key/Value字典集合
  35. enumDic = GetEnumDictionaryItems(enumType);
  36. // 缓存
  37. EnumNameValueDict[enumType] = enumDic;
  38. return enumDic;
  39. }
  40. /// <summary>
  41. /// 获取枚举对象Key与名称的字典
  42. /// </summary>
  43. /// <param name="enumType"></param>
  44. /// <returns></returns>
  45. private static Dictionary<int, string> GetEnumDictionaryItems(this Type enumType)
  46. {
  47. // 获取类型的字段,初始化一个有限长度的字典
  48. var enumFields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
  49. Dictionary<int, string> enumDic = new(enumFields.Length);
  50. // 遍历字段数组获取key和name
  51. foreach (var enumField in enumFields)
  52. {
  53. var intValue = (int)enumField.GetValue(enumType);
  54. enumDic[intValue] = enumField.Name;
  55. }
  56. return enumDic;
  57. }
  58. /// <summary>
  59. /// 获取枚举类型key与描述的字典(缓存)
  60. /// </summary>
  61. /// <param name="enumType"></param>
  62. /// <returns></returns>
  63. /// <exception cref="Exception"></exception>
  64. public static Dictionary<int, string> GetEnumDescDictionary(this Type enumType)
  65. {
  66. if (!enumType.IsEnum)
  67. throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
  68. // 查询缓存
  69. var enumDic = EnumDisplayValueDict.ContainsKey(enumType)
  70. ? EnumDisplayValueDict[enumType]
  71. : new Dictionary<int, string>();
  72. if (enumDic.Count != 0)
  73. return enumDic;
  74. // 取枚举类型的Key/Value字典集合
  75. enumDic = GetEnumDescDictionaryItems(enumType);
  76. // 缓存
  77. EnumDisplayValueDict[enumType] = enumDic;
  78. return enumDic;
  79. }
  80. /// <summary>
  81. /// 获取枚举类型key与描述的字典(没有描述则获取name)
  82. /// </summary>
  83. /// <param name="enumType"></param>
  84. /// <returns></returns>
  85. /// <exception cref="Exception"></exception>
  86. private static Dictionary<int, string> GetEnumDescDictionaryItems(this Type enumType)
  87. {
  88. // 获取类型的字段,初始化一个有限长度的字典
  89. var enumFields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
  90. Dictionary<int, string> enumDic = new(enumFields.Length);
  91. // 遍历字段数组获取key和name
  92. foreach (var enumField in enumFields)
  93. {
  94. var intValue = (int)enumField.GetValue(enumType);
  95. var desc = enumField.GetDescriptionValue<DescriptionAttribute>();
  96. enumDic[intValue] = desc != null && !string.IsNullOrEmpty(desc.Description) ? desc.Description : enumField.Name;
  97. }
  98. return enumDic;
  99. }
  100. /// <summary>
  101. /// 从程序集中查找指定枚举类型
  102. /// </summary>
  103. /// <param name="assembly"></param>
  104. /// <param name="typeName"></param>
  105. /// <returns></returns>
  106. public static Type TryToGetEnumType(Assembly assembly, string typeName)
  107. {
  108. // 枚举缓存为空则重新加载枚举类型字典
  109. _enumTypeDict ??= LoadEnumTypeDict(assembly);
  110. // 按名称查找
  111. return _enumTypeDict.ContainsKey(typeName) ? _enumTypeDict[typeName] : null;
  112. }
  113. /// <summary>
  114. /// 从程序集中加载所有枚举类型
  115. /// </summary>
  116. /// <param name="assembly"></param>
  117. /// <returns></returns>
  118. private static ConcurrentDictionary<string, Type> LoadEnumTypeDict(Assembly assembly)
  119. {
  120. // 取程序集中所有类型
  121. var typeArray = assembly.GetTypes();
  122. // 过滤非枚举类型,转成字典格式并返回
  123. var dict = typeArray.Where(o => o.IsEnum).ToDictionary(o => o.Name, o => o);
  124. ConcurrentDictionary<string, Type> enumTypeDict = new(dict);
  125. return enumTypeDict;
  126. }
  127. /// <summary>
  128. /// 获取枚举的Description
  129. /// </summary>
  130. /// <param name="value"></param>
  131. /// <returns></returns>
  132. public static string GetDescription(this System.Enum value)
  133. {
  134. return value.GetType().GetMember(value.ToString()).FirstOrDefault()?.GetCustomAttribute<DescriptionAttribute>()
  135. ?.Description;
  136. }
  137. /// <summary>
  138. /// 获取枚举的Description
  139. /// </summary>
  140. /// <param name="value"></param>
  141. /// <returns></returns>
  142. public static string GetDescription(this object value)
  143. {
  144. return value.GetType().GetMember(value.ToString() ?? string.Empty).FirstOrDefault()
  145. ?.GetCustomAttribute<DescriptionAttribute>()?.Description;
  146. }
  147. /// <summary>
  148. /// 将枚举转成枚举信息集合
  149. /// </summary>
  150. /// <param name="type"></param>
  151. /// <returns></returns>
  152. public static List<EnumEntity> EnumToList(this Type type)
  153. {
  154. if (!type.IsEnum)
  155. throw new ArgumentException("Type '" + type.Name + "' is not an enum.");
  156. var arr = System.Enum.GetNames(type);
  157. return arr.Select(sl =>
  158. {
  159. var item = System.Enum.Parse(type, sl);
  160. return new EnumEntity
  161. {
  162. Name = item.ToString(),
  163. Describe = item.GetDescription() ?? item.ToString(),
  164. Value = item.GetHashCode()
  165. };
  166. }).ToList();
  167. }
  168. /// <summary>
  169. /// 枚举ToList
  170. /// </summary>
  171. /// <typeparam name="T"></typeparam>
  172. /// <param name="type"></param>
  173. /// <returns></returns>
  174. public static List<T> EnumToList<T>(this Type type)
  175. {
  176. if (!type.IsEnum)
  177. throw new ArgumentException("Type '" + type.Name + "' is not an enum.");
  178. var arr = System.Enum.GetNames(type);
  179. return arr.Select(name => (T)System.Enum.Parse(type, name)).ToList();
  180. }
  181. }
  182. /// <summary>
  183. /// 枚举实体
  184. /// </summary>
  185. public class EnumEntity
  186. {
  187. /// <summary>
  188. /// 枚举的描述
  189. /// </summary>
  190. public string Describe { set; get; }
  191. /// <summary>
  192. /// 枚举名称
  193. /// </summary>
  194. public string Name { set; get; }
  195. /// <summary>
  196. /// 枚举对象的值
  197. /// </summary>
  198. public int Value { set; get; }
  199. }