EnumExtension.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // 此源代码遵循位于源代码树根目录中的 LICENSE 文件的许可证。
  2. //
  3. // 必须在法律法规允许的范围内正确使用,严禁将其用于非法、欺诈、恶意或侵犯他人合法权益的目的。
  4. namespace Admin.NET.Core;
  5. /// <summary>
  6. /// 枚举拓展
  7. /// </summary>
  8. public static class EnumExtension
  9. {
  10. // 枚举显示字典缓存
  11. private static readonly ConcurrentDictionary<Type, Dictionary<int, string>> EnumDisplayValueDict = new();
  12. // 枚举值字典缓存
  13. private static readonly ConcurrentDictionary<Type, Dictionary<int, string>> EnumNameValueDict = new();
  14. // 枚举类型缓存
  15. private static ConcurrentDictionary<string, Type> _enumTypeDict;
  16. /// <summary>
  17. /// 获取枚举对象Key与名称的字典(缓存)
  18. /// </summary>
  19. /// <param name="enumType"></param>
  20. /// <returns></returns>
  21. public static Dictionary<int, string> GetEnumDictionary(this Type enumType)
  22. {
  23. if (!enumType.IsEnum)
  24. throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
  25. // 查询缓存
  26. var enumDic = EnumNameValueDict.ContainsKey(enumType) ? EnumNameValueDict[enumType] : new Dictionary<int, string>();
  27. if (enumDic.Count != 0)
  28. return enumDic;
  29. // 取枚举类型的Key/Value字典集合
  30. enumDic = GetEnumDictionaryItems(enumType);
  31. // 缓存
  32. EnumNameValueDict[enumType] = enumDic;
  33. return enumDic;
  34. }
  35. /// <summary>
  36. /// 获取枚举对象Key与名称的字典
  37. /// </summary>
  38. /// <param name="enumType"></param>
  39. /// <returns></returns>
  40. private static Dictionary<int, string> GetEnumDictionaryItems(this Type enumType)
  41. {
  42. // 获取类型的字段,初始化一个有限长度的字典
  43. var enumFields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
  44. Dictionary<int, string> enumDic = new(enumFields.Length);
  45. // 遍历字段数组获取key和name
  46. foreach (var enumField in enumFields)
  47. {
  48. var intValue = (int)enumField.GetValue(enumType);
  49. enumDic[intValue] = enumField.Name;
  50. }
  51. return enumDic;
  52. }
  53. /// <summary>
  54. /// 获取枚举类型key与描述的字典(缓存)
  55. /// </summary>
  56. /// <param name="enumType"></param>
  57. /// <returns></returns>
  58. /// <exception cref="Exception"></exception>
  59. public static Dictionary<int, string> GetEnumDescDictionary(this Type enumType)
  60. {
  61. if (!enumType.IsEnum)
  62. throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
  63. // 查询缓存
  64. var enumDic = EnumDisplayValueDict.ContainsKey(enumType)
  65. ? EnumDisplayValueDict[enumType]
  66. : new Dictionary<int, string>();
  67. if (enumDic.Count != 0)
  68. return enumDic;
  69. // 取枚举类型的Key/Value字典集合
  70. enumDic = GetEnumDescDictionaryItems(enumType);
  71. // 缓存
  72. EnumDisplayValueDict[enumType] = enumDic;
  73. return enumDic;
  74. }
  75. /// <summary>
  76. /// 获取枚举类型key与描述的字典(没有描述则获取name)
  77. /// </summary>
  78. /// <param name="enumType"></param>
  79. /// <returns></returns>
  80. /// <exception cref="Exception"></exception>
  81. private static Dictionary<int, string> GetEnumDescDictionaryItems(this Type enumType)
  82. {
  83. // 获取类型的字段,初始化一个有限长度的字典
  84. var enumFields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
  85. Dictionary<int, string> enumDic = new(enumFields.Length);
  86. // 遍历字段数组获取key和name
  87. foreach (var enumField in enumFields)
  88. {
  89. var intValue = (int)enumField.GetValue(enumType);
  90. var desc = enumField.GetDescriptionValue<DescriptionAttribute>();
  91. enumDic[intValue] = desc != null && !string.IsNullOrEmpty(desc.Description) ? desc.Description : enumField.Name;
  92. }
  93. return enumDic;
  94. }
  95. /// <summary>
  96. /// 从程序集中查找指定枚举类型
  97. /// </summary>
  98. /// <param name="assembly"></param>
  99. /// <param name="typeName"></param>
  100. /// <returns></returns>
  101. public static Type TryToGetEnumType(Assembly assembly, string typeName)
  102. {
  103. // 枚举缓存为空则重新加载枚举类型字典
  104. _enumTypeDict ??= LoadEnumTypeDict(assembly);
  105. // 按名称查找
  106. return _enumTypeDict.ContainsKey(typeName) ? _enumTypeDict[typeName] : null;
  107. }
  108. /// <summary>
  109. /// 从程序集中加载所有枚举类型
  110. /// </summary>
  111. /// <param name="assembly"></param>
  112. /// <returns></returns>
  113. private static ConcurrentDictionary<string, Type> LoadEnumTypeDict(Assembly assembly)
  114. {
  115. // 取程序集中所有类型
  116. var typeArray = assembly.GetTypes();
  117. // 过滤非枚举类型,转成字典格式并返回
  118. var dict = typeArray.Where(o => o.IsEnum).ToDictionary(o => o.Name, o => o);
  119. ConcurrentDictionary<string, Type> enumTypeDict = new(dict);
  120. return enumTypeDict;
  121. }
  122. /// <summary>
  123. /// 获取枚举的Description
  124. /// </summary>
  125. /// <param name="value"></param>
  126. /// <returns></returns>
  127. public static string GetDescription(this System.Enum value)
  128. {
  129. return value.GetType().GetMember(value.ToString()).FirstOrDefault()?.GetCustomAttribute<DescriptionAttribute>()
  130. ?.Description;
  131. }
  132. /// <summary>
  133. /// 获取枚举的Description
  134. /// </summary>
  135. /// <param name="value"></param>
  136. /// <returns></returns>
  137. public static string GetDescription(this object value)
  138. {
  139. return value.GetType().GetMember(value.ToString() ?? string.Empty).FirstOrDefault()
  140. ?.GetCustomAttribute<DescriptionAttribute>()?.Description;
  141. }
  142. /// <summary>
  143. /// 将枚举转成枚举信息集合
  144. /// </summary>
  145. /// <param name="type"></param>
  146. /// <returns></returns>
  147. public static List<EnumEntity> EnumToList(this Type type)
  148. {
  149. if (!type.IsEnum)
  150. throw new ArgumentException("Type '" + type.Name + "' is not an enum.");
  151. var arr = System.Enum.GetNames(type);
  152. return arr.Select(sl =>
  153. {
  154. var item = System.Enum.Parse(type, sl);
  155. return new EnumEntity
  156. {
  157. Name = item.ToString(),
  158. Describe = item.GetDescription() ?? item.ToString(),
  159. Value = item.GetHashCode()
  160. };
  161. }).ToList();
  162. }
  163. /// <summary>
  164. /// 枚举ToList
  165. /// </summary>
  166. /// <typeparam name="T"></typeparam>
  167. /// <param name="type"></param>
  168. /// <returns></returns>
  169. public static List<T> EnumToList<T>(this Type type)
  170. {
  171. if (!type.IsEnum)
  172. throw new ArgumentException("Type '" + type.Name + "' is not an enum.");
  173. var arr = System.Enum.GetNames(type);
  174. return arr.Select(name => (T)System.Enum.Parse(type, name)).ToList();
  175. }
  176. }
  177. /// <summary>
  178. /// 枚举实体
  179. /// </summary>
  180. public class EnumEntity
  181. {
  182. /// <summary>
  183. /// 枚举的描述
  184. /// </summary>
  185. public string Describe { set; get; }
  186. /// <summary>
  187. /// 枚举名称
  188. /// </summary>
  189. public string Name { set; get; }
  190. /// <summary>
  191. /// 枚举对象的值
  192. /// </summary>
  193. public int Value { set; get; }
  194. }