一網打盡列舉操作 .net core

FreeTimeWorker發表於2020-06-12

本文介紹如何使用列舉以及,如何將列舉型別更好的應用於專案中,看完本文可以有序的將專案中的列舉更容易的使用到每個角落。

1,分析列舉

 /// <summary>
    /// 性別
    /// </summary>
    public enum Gender
    {
        /// <summary>
        ////// </summary>
        
        Man = 0,
        /// <summary>
        ////// </summary>
        
        Women = 1
    }

 

如1所示,這是一個非常普通的列舉類,在專案中使用的話,一般都會將它作為某實體的一個屬性,這個時候問題就來了,在頁面裡邊我們是需要拿到與之相關的描述資訊和對應的值作為一個下拉框或者checkbox讓使用者去選擇,同時也不可以將Disable和enable作為給使用者最終展示的資訊,需要去手動去拼,於是有了如下的方式

2,列舉類資訊完善,增加描述資訊

 /// <summary>
    /// 性別
    /// </summary>
    public enum Gender
    {
        /// <summary>
        ////// </summary>
        [Description("")]
        Man = 0,
        /// <summary>
        ////// </summary>
        [Description("女")]
        Women = 1
    }

再給列舉增加一個擴充套件方法

 /// <summary>
        /// 獲取到對應列舉的描述-沒有描述資訊,返回列舉值
        /// </summary>
        /// <param name="enum"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum @enum)
        {
            Type type = @enum.GetType();
            string name = Enum.GetName(type, @enum);
            if (name == null)
            {
                return null;
            }
            FieldInfo field = type.GetField(name);
            if (!(Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attribute))
            {
                return name;
            }
            return attribute?.Description;
        }

 好像到這一步的時候問題可以得到解決,通過getdescroption()這類的方法可以去獲取到與列舉相應的描述資訊用於展示,但是這也僅限於在mvc模式下,通過viewbag將列舉的類中的每一項都加到列舉集合中返回給頁面,在頁面裡邊遍歷,如果列舉型別很多,那麼這型別的重複邏輯就會很多,非常的心煩。

如果可以將這些操作做一個封裝,用一個介面可以返回所有列舉型別的相關資訊,就好了,於是有了如下的做法

1 建立一個描述列舉的類 

 public class EnumModel
    {
        /// <summary>
        ///列舉原始值
        /// </summary>
        public ValueType Source { get; set; }
        /// <summary>
        /// 描述資訊
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// value
        /// </summary>
        public int Value { get; set; }
    }

2,寫一個方法通過傳遞一個列舉類型別去得到List<EnumModel>

public static List<EnumModel> GetEnumListModels<T>()
        {
            var model = default(T);
            FieldInfo[] fieldinfo = typeof(T).GetFields();
            List<EnumModel> result = new List<EnumModel>();
            foreach (FieldInfo field in fieldinfo)
            {
                EnumModel enumModel = new EnumModel();
                if (!(Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attribute))
                {
                    enumModel.Description = field.GetValue(model).ToString();
                }
                else
                {
                    enumModel.Description = attribute.Description;
                }
                enumModel.Value = field.GetValue(model).GetHashCode();
                enumModel.Source = field.GetValue(model) as ValueType;
                if (field.GetValue(model).ToString() != "0")
                {
                    result.Add(enumModel);
                }
                
            }
            return result;
        }

3,寫一個介面,輸入列舉的類的名稱,呼叫2中的方法,得到具體的返回資訊

[Route("[controller]/{name}")]
        public IActionResult GetEnumList(string name)
        {
            Assembly assembly = Assembly.Load("Ftw");
            Type t = assembly.GetType(string.Concat("Ftw.Enum.", name), throwOnError: false, ignoreCase: true);
            if (t == null)
            {
                throw new ServiceException(string.Concat("請確保列舉[", name, "]在 Ftw.Enum 中定義"));
            }
            Type enumhelp = typeof(EnumHelper);
            var obj = enumhelp.GetMethod("GetEnumListModels").MakeGenericMethod(t);
            return Json(obj.Invoke(t, null));
        }

  解釋一下:Ftw是類庫的名稱,Enum是Ftw類庫下的一個資料夾,所有的列舉類都在Enum下邊放著,EnumHelper是 2 中方法【GetEnumListModels】所在的類,通過反射程式集得到列舉型別,通過反射程式集將型別傳入GetEnumListModels作為 T 最後執行方法的到list.

比如  Gender的呼叫,假如 GetEnumList所在的controller是EnumController,那麼呼叫就是通過  Enum/Gender ,對於.net core, mvc .net core api這類專案這種方式是非常有幫助的。

 

相關文章