using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; namespace LifePayment.Domain.Shared; /// <summary> /// 枚举拓展 /// </summary> public static partial class EnumExtension { // 枚举显示å—å…¸ç¼“å˜ private static readonly ConcurrentDictionary<Type, Dictionary<int, string>> EnumDisplayValueDict = new(); // 枚举值å—å…¸ç¼“å˜ private static readonly ConcurrentDictionary<Type, Dictionary<int, string>> EnumNameValueDict = new(); // æžšä¸¾ç±»åž‹ç¼“å˜ private static ConcurrentDictionary<string, Type> _enumTypeDict; /// <summary> /// èŽ·å–æžšä¸¾å¯¹è±¡Key与åç§°çš„å—典(缓å˜ï¼‰ /// </summary> /// <param name="enumType"></param> /// <returns></returns> public static Dictionary<int, string> GetEnumDictionary(this Type enumType) { if (!enumType.IsEnum) throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); // æŸ¥è¯¢ç¼“å˜ var enumDic = EnumNameValueDict.ContainsKey(enumType) ? EnumNameValueDict[enumType] : new Dictionary<int, string>(); if (enumDic.Count != 0) return enumDic; // å–æžšä¸¾ç±»åž‹çš„Key/Valueå—å…¸é›†åˆ enumDic = GetEnumDictionaryItems(enumType); // ç¼“å˜ EnumNameValueDict[enumType] = enumDic; return enumDic; } /// <summary> /// èŽ·å–æžšä¸¾å¯¹è±¡Key与åç§°çš„å—å…¸ /// </summary> /// <param name="enumType"></param> /// <returns></returns> private static Dictionary<int, string> GetEnumDictionaryItems(this Type enumType) { // 获å–ç±»åž‹çš„å—æ®µï¼Œåˆå§‹åŒ–一个有é™é•¿åº¦çš„å—å…¸ var enumFields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); Dictionary<int, string> enumDic = new(enumFields.Length); // éåŽ†å—æ®µæ•°ç»„获å–keyå’Œname foreach (var enumField in enumFields) { var intValue = (int)enumField.GetValue(enumType); enumDic[intValue] = enumField.Name; } return enumDic; } /// <summary> /// èŽ·å–æžšä¸¾ç±»åž‹key与æè¿°çš„å—典(缓å˜ï¼‰ /// </summary> /// <param name="enumType"></param> /// <returns></returns> /// <exception cref="Exception"></exception> public static Dictionary<int, string> GetEnumDescDictionary(this Type enumType) { if (!enumType.IsEnum) throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); // æŸ¥è¯¢ç¼“å˜ var enumDic = EnumDisplayValueDict.ContainsKey(enumType) ? EnumDisplayValueDict[enumType] : new Dictionary<int, string>(); if (enumDic.Count != 0) return enumDic; // å–æžšä¸¾ç±»åž‹çš„Key/Valueå—å…¸é›†åˆ enumDic = GetEnumDescDictionaryItems(enumType); // ç¼“å˜ EnumDisplayValueDict[enumType] = enumDic; return enumDic; } /// <summary> /// èŽ·å–æžšä¸¾ç±»åž‹key与æè¿°çš„å—典(没有æè¿°åˆ™èŽ·å–name) /// </summary> /// <param name="enumType"></param> /// <returns></returns> /// <exception cref="Exception"></exception> private static Dictionary<int, string> GetEnumDescDictionaryItems(this Type enumType) { // 获å–ç±»åž‹çš„å—æ®µï¼Œåˆå§‹åŒ–一个有é™é•¿åº¦çš„å—å…¸ var enumFields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); Dictionary<int, string> enumDic = new(enumFields.Length); // éåŽ†å—æ®µæ•°ç»„获å–keyå’Œname foreach (var enumField in enumFields) { var intValue = (int)enumField.GetValue(enumType); var desc = enumField.GetCustomAttribute<DescriptionAttribute>(); enumDic[intValue] = desc != null && !string.IsNullOrEmpty(desc.Description) ? desc.Description : enumField.Name; } return enumDic; } /// <summary> /// 从程åºé›†ä¸æŸ¥æ‰¾æŒ‡å®šæžšä¸¾ç±»åž‹ /// </summary> /// <param name="assembly"></param> /// <param name="typeName"></param> /// <returns></returns> public static Type TryToGetEnumType(Assembly assembly, string typeName) { // 枚举缓å˜ä¸ºç©ºåˆ™é‡æ–°åŠ è½½æžšä¸¾ç±»åž‹å—å…¸ _enumTypeDict ??= LoadEnumTypeDict(assembly); // 按å称查找 return _enumTypeDict.ContainsKey(typeName) ? _enumTypeDict[typeName] : null; } /// <summary> /// 从程åºé›†ä¸åŠ è½½æ‰€æœ‰æžšä¸¾ç±»åž‹ /// </summary> /// <param name="assembly"></param> /// <returns></returns> private static ConcurrentDictionary<string, Type> LoadEnumTypeDict(Assembly assembly) { // å–程åºé›†ä¸æ‰€æœ‰ç±»åž‹ var typeArray = assembly.GetTypes(); // è¿‡æ»¤éžæžšä¸¾ç±»åž‹ï¼Œè½¬æˆå—å…¸æ ¼å¼å¹¶è¿”回 var dict = typeArray.Where(o => o.IsEnum).ToDictionary(o => o.Name, o => o); ConcurrentDictionary<string, Type> enumTypeDict = new(dict); return enumTypeDict; } /// <summary> /// èŽ·å–æžšä¸¾çš„Description /// </summary> /// <param name="value"></param> /// <returns></returns> public static string GetDescription<T>(this T value) where T : Enum { return GetEnumDescDictionary(typeof(T))[value.GetHashCode()]; } /// <summary> /// èŽ·å–æžšä¸¾çš„Description /// </summary> /// <param name="value"></param> /// <returns></returns> public static string GetDescription(this object value) { if (value == null) { return null; } return value.GetType().GetMember(value.ToString() ?? string.Empty).FirstOrDefault() ?.GetCustomAttribute<DescriptionAttribute>()?.Description; } /// <summary> /// å°†æžšä¸¾è½¬æˆæžšä¸¾ä¿¡æ¯é›†åˆ /// </summary> /// <param name="type"></param> /// <returns></returns> public static List<EnumEntity> EnumToList(this Type type) { if (!type.IsEnum) throw new ArgumentException("Type '" + type.Name + "' is not an enum."); var arr = System.Enum.GetNames(type); return arr.Select(sl => { var item = System.Enum.Parse(type, sl); return new EnumEntity { Name = item.ToString(), Describe = item.GetDescription() ?? item.ToString(), Value = (int)item }; }).ToList(); } /// <summary> /// å°†æžšä¸¾è½¬æˆæžšä¸¾ä¿¡æ¯é›†åˆ /// </summary> /// <param name="type"></param> /// <returns></returns> public static List<EnumEntity<T>> EnumToList<T>(this Type type) { if (!type.IsEnum) throw new ArgumentException("Type '" + type.Name + "' is not an enum."); var arr = System.Enum.GetNames(type); return arr.Select(sl => { var item = System.Enum.Parse(type, sl); return new EnumEntity<T> { Name = item.ToString(), Describe = item.GetDescription() ?? item.ToString(), Value = (T)item }; }).ToList(); } /// <summary> /// 枚举ToList /// </summary> /// <typeparam name="T"></typeparam> /// <param name="type"></param> /// <returns></returns> public static List<T> EnumToEnumList<T>(this Type type) { if (!type.IsEnum) throw new ArgumentException("Type '" + type.Name + "' is not an enum."); var arr = System.Enum.GetNames(type); return arr.Select(name => (T)System.Enum.Parse(type, name)).ToList(); } /// <summary> /// æ˜¯å¦æ˜¯æžšä¸¾ä¸çš„值 /// </summary> /// <param name="value"></param> /// <returns></returns> public static bool IsEnumValue(this Enum value) { return Enum.IsDefined(value.GetType(), value); } } /// <summary> /// 枚举实体 /// </summary> public class EnumEntity<T> { /// <summary> /// 枚举的æè¿° /// </summary> public string Describe { set; get; } /// <summary> /// 枚举åç§° /// </summary> public string Name { set; get; } /// <summary> /// 枚举对象的值 /// </summary> public T Value { set; get; } } /// <summary> /// 枚举实体 /// </summary> public class EnumEntity : EnumEntity<int> { } /// <summary> /// åŒ…å«æžšä¸¾ç±»åž‹çš„æžšä¸¾ä¿¡æ¯ /// </summary> public class EnumEntityAndEnumType<T> { /// <summary> /// 枚举类型åç§° /// </summary> public string EnumName { get; set; } /// <summary> /// 枚举值明细 /// </summary> public List<EnumEntity<T>> EnumEntitiy { get; set; } } /// <summary> /// åŒ…å«æžšä¸¾ç±»åž‹çš„æžšä¸¾ä¿¡æ¯ /// </summary> public class EnumEntityAndEnumType : EnumEntityAndEnumType<int> { }