1. 程式人生 > 實用技巧 >根據列舉的型別名稱獲取列舉型別列表

根據列舉的型別名稱獲取列舉型別列表

前言

前端進行搜尋或其他操作時需要獲取列舉列表,每個列舉寫一個介面比較繁瑣,所以這裡根據列舉型別名獲取列表

程式碼

EnumDto.cs 返回的列舉資訊類

public class EnumDto
{
    /// <summary>
    /// 列舉code
    /// </summary>
    public string Code { get; set; }
    
    /// <summary>
    /// 值
    /// </summary>
    public int Value { get; set; }
    
    /// <summary>
    /// 描述
    /// </summary>
    public string Description { get; set; }
}

EnumExpansion.cs 列舉拓展類

using System.ComponentModel;
using System.Reflection;

namespace System
{
    public static class EnumExpansion
    {
        /// <summary>
        /// 獲取列舉項上的<see cref="DescriptionAttribute"/>特性的文字描述
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToDescription(this Enum enumValue)
        {
            string value = enumValue.ToString();
            FieldInfo field = enumValue.GetType().GetField(value);
            object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);    //獲取描述屬性
            if (objs.Length == 0)    //當描述屬性沒有時,直接返回名稱
                return value;
            DescriptionAttribute descriptionAttribute = (DescriptionAttribute)objs[0];
            return descriptionAttribute.Description;
        }
    }
}

EnumException.cs 列舉異常類

public class EnumException:Exception
{
    public EnumException()
    {

    }
    public EnumException(string message):base(message)
    {

    }
}

EnumHelper.cs 列舉幫助類

/// <summary>
/// 列舉幫助類
/// </summary>
public class EnumHelper
{

    private static ConcurrentDictionary<string, Assembly> AssemblyList = new ConcurrentDictionary<string, Assembly>();

    /// <summary>
    /// 根據列舉程式碼獲取列舉列表
    /// </summary>
    /// <param name="assembly">程式集名稱集合</param>
    /// <param name="namespaces">名稱空間名稱集合</param>
    /// <param name="code">列舉名稱</param>
    /// <returns></returns>
    public static List<EnumDto> GetEnumListByCode(IEnumerable<string> assemblys,IEnumerable<string> namespaces,string EnumCode)
    {
        assemblys = assemblys.Distinct();
        namespaces = namespaces.Distinct();
        var Inexistentassembly = assemblys.Except(AssemblyList?.Select(o=>o.Key));
        foreach (var assembly in Inexistentassembly)
            AssemblyList.TryAdd(assembly, System.Reflection.Assembly.Load(assembly));
        List<Type> enumlist = new List<Type>();
        List<string> enumNamespanList = new List<string>();
        foreach (var enumNamespace in namespaces)
        {
            foreach (var assembly in AssemblyList)
            {
                var enumInfo = assembly.Value.CreateInstance($"{enumNamespace}.{EnumCode}", false);
                if (enumInfo != null)
                {
                    enumNamespanList.Add(enumNamespace);
                    enumlist.Add(enumInfo.GetType());
                }
            }
        }
        if (enumlist.Count == 0) return default;
        if (enumlist.Count > 1)
            throw new EnumException($"列舉【{EnumCode}】存在多個,請檢查名稱空間【{string.Join(',', enumNamespanList)}】");
        var enums = Enum.GetValues(enumlist.FirstOrDefault());
        List<EnumDto> enumDic = new List<EnumDto>(); 
        foreach (Enum item in enums)
        {
            enumDic.Add(new EnumDto() { Code = item.ToString(), Value = Convert.ToInt32(item), Description = item.ToDescription() });
        }
        return enumDic;
    }
}

如果多個程式集 和 多個命名空間出現一樣的列舉型別將會丟擲異常

使用

運行當前方法的程式集需要引用使用到的程式集

例如當前使用到的程式集名稱為EnumList

當前使到的名稱空間為EnumList.Enums

當前需要獲取的列舉型別為UserType

static void Main(string[] args)
{

    var enumName = "UserType";
    var dic = EnumHelper.GetEnumListByCode(new[] { "EnumList" },new[] { "EnumList.Enums" }, enumName);
    foreach (var item in dic)
    {
        Console.WriteLine($"code:{item.Code},value:{item.Value},描述:{item.Description}");
    }
    Console.ReadKey();
}