C# Enum列舉型別操作擴充套件類

eedc發表於2017-05-19

使用示例:

using System.ComponentModel;

namespace SchoolEnterpriseManageSys.Enum
{
    /// <summary>
    /// 申報級別
    /// </summary>
    public enum ReportLevel : int
    {
        /// <summary>
        ////// </summary>
        [Description("")]
        School = 2,
        /// <summary>
        ////// </summary>
        [Description("")]
        Province = 4,
        /// <summary>
        ////// </summary>
        [Description("")]
        Ministry = 8

    }
}

 獲取列舉Description值:EnumExtensions.GetDescription(...)

using System;
using System.ComponentModel.DataAnnotations;

namespace SchoolEnterpriseManageSys.Project.Dto
{
    public class BeAssociatedProjectDto
    {
        public Guid Id { get; set; }
        /// <summary>
        /// 型別
        /// </summary>
        public Enum.ProjectType Type { get; set; }
        public string TypeText
        {
            get
            {
                return Utilities.EnumHelper.EnumExtensions.GetDescription(this.Type);
            }
        }
        /// <summary>
        /// 型別標識
        /// </summary>
        public Guid ProjectTypeId { get; set; }
        /// <summary>
        /// 專案編號
        /// </summary>
        [StringLength(32)]
        public string Number { get; set; }
        /// <summary>
        /// 專案名稱
        /// </summary>
        [StringLength(32)]
        public string ProjectName { get; set; }
        /// <summary>
        /// 關聯專案標識 
        /// </summary>
        public Guid? RelateProjectId { get; set; }
        /// <summary>
        /// 建立時間
        /// </summary>
        public DateTime CreateTime { get; set; }
    }
}

 

 以下是原始碼  

1、ArrayExtensions.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UUT.TeamCenter.Utility.EnumHelper
{
    /// <summary>
    /// 陣列,佇列物件的列表類
    /// </summary>
    public static class ArrayExtensions
    {
        /// <summary>
        /// 擴充套件 Dictionary 根據Value反向查詢Key的方法
        /// </summary>
        public static T1 Get<T1, T2>(this IEnumerable<KeyValuePair<T1, T2>> list, T2 t2)
        {
            foreach (KeyValuePair<T1, T2> obj in list)
                if (obj.Value.Equals(t2)) return obj.Key;
            return default(T1);
        }

        /// <summary>
        /// 擴充套件陣列方法 可以在前或者後插入一個物件
        /// </summary>
        /// <param name="obj">要插入的物件</param>
        /// <param name="place">位置 after/before</param>
        /// <returns></returns>
        public static IEnumerable<T> Inject<T>(this IEnumerable<T> list, T obj, ArrayInjectPlace place = ArrayInjectPlace.Top)
        {
            T[] list2 = new T[list.Count() + 1];
            int index = 0;
            foreach (T t in list)
            {
                list2[place == ArrayInjectPlace.Bottom ? index : index + 1] = t;
            }
            list2[place == ArrayInjectPlace.Bottom ? list.Count() : 0] = obj;
            return list2;
        }

        /// <summary>
        /// 將陣列合併成為一個字串
        /// </summary>
        public static string Join<T>(this IEnumerable<T> list, char? c = ',')
        {
            return list.Join(c.ToString());
        }

        public static string Join<T>(this IEnumerable<T> list, string split)
        {
            return string.Join(split, list);
        }
        /// <summary>
        /// 按指定條件過濾陣列
        /// </summary>
        /// <param name="ac">預設為過濾重複</param>
        public static IEnumerable<T> Filter<T>(this IEnumerable<T> list, ArrayFilterRule filterRule = ArrayFilterRule.NoRepeater)
        {
            List<T> list2 = new List<T>();
            foreach (T t in list)
            {
                if (!list2.Contains(t)) list2.Add(t);
            }
            return list2;
        }
        /// <summary>
        /// 合併陣列 並且去除重複項
        /// </summary>
        /// <param name="converter">要比較的欄位</param>
        public static List<T> Merge<T, TOutput>(this IEnumerable<T> objList, Converter<T, TOutput> converter, params IEnumerable<T>[] objs)
        {
            List<T> list = objList.ToList();
            foreach (var obj in objs)
            {
                list.AddRange(obj.ToList().FindAll(t => !list.Exists(t1 => converter(t1).Equals(converter(t)))));
            }
            return list;
        }



        /// <summary>
        /// 獲取陣列的索引項。 如果超出則返回型別的預設值
        /// </summary>
        public static T GetIndex<T>(this IEnumerable<T> list, int index)
        {
            if (list == null || index >= list.Count() || index < 0) return default(T);
            return list.ToArray()[index];
        }

        /// <summary>
        /// 把陣列所有元素,按照“引數=引數值”的模式用“&”字元拼接成字串
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="list"></param>
        public static string ToQueryString<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> list)
        {
            return list.ToList().ConvertAll(t => string.Format("{0}={1}", t.Key, t.Value)).Join("&");
        }

        /// <summary>
        /// 除去陣列中的空值和指定名稱的引數並以字母a到z的順序排序
        /// </summary>
        /// <param name="filter">過濾規則 預設做為空判斷</param>
        public static IEnumerable<KeyValuePair<TKey, TValue>> Filter<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> list, Func<TKey, TValue, bool> filter = null)
        {
            if (filter == null)
            {
                filter = (key, value) =>
                {
                    return !string.IsNullOrEmpty(key.ToString()) && value != null;
                };
            }
            foreach (var item in list)
            {
                if (filter(item.Key, item.Value))
                    yield return new KeyValuePair<TKey, TValue>(item.Key, item.Value);
            }
        }

        /// <summary>
        /// 不包含指定的Key
        /// </summary>
        public static IEnumerable<KeyValuePair<TKey, TValue>> Filter<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> list, params TKey[] filter)
        {
            return list.Filter((key, value) =>
            {
                return !string.IsNullOrEmpty(key.ToString()) && value != null && !filter.Contains(key);
            });
        }

        /// <summary>
        /// 按照Key從小大大拍列
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="list"></param>
        public static void Sort<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> list)
        {
            list = list.ToList().OrderBy(t => t.Key);
        }

        /// <summary>
        /// 獲取父級的繼承樹(最多支援32級)
        /// 包括自己
        /// </summary>
        /// <typeparam name="TValue">主鍵型別</typeparam>
        /// <param name="obj">要查詢的陣列物件</param>
        /// <param name="id">當前物件的主鍵值</param>
        /// <param name="value">主鍵欄位</param>
        /// <param name="parent">父級欄位</param>
        /// <returns></returns>
        public static List<T> GetParent<T, TValue>(this List<T> obj, TValue id, Func<T, TValue> value, Func<T, TValue> parent)
        {
            int count = 0;
            T t = obj.Find(m => value.Invoke(m).Equals(id));
            List<T> list = new List<T>();
            while (t != null)
            {
                if (count > 32) break;
                list.Add(t);
                t = obj.Find(m => value.Invoke(m).Equals(parent.Invoke(t)));
                count++;
            }
            return list;
        }

        /// <summary>
        /// 獲取子集列表(包括自己)
        /// </summary>
        public static void GetChild<T, TValue>(this List<T> obj, TValue id, Func<T, TValue> value, Func<T, TValue> parent, ref List<T> list)
        {
            if (list == null) list = new List<T>();
            var objT = obj.Find(t => value.Invoke(t).Equals(id));
            if (objT != null)
            {
                list.Add(objT);
                foreach (T t in obj.FindAll(m => parent.Invoke(m).Equals(id)))
                {
                    obj.GetChild(value.Invoke(t), value, parent, ref list);
                }
            }
        }

        /// <summary>
        /// 獲取樹形結構的子集執行方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="obj">當前物件</param>
        /// <param name="id">當前父節點</param>
        /// <param name="value">獲取主鍵的委託</param>
        /// <param name="parent">獲取父值的委託</param>
        /// <param name="action">委託執行的方法 int 為當前的深度</param>
        /// <param name="depth">當前的深度</param>
        public static void GetTree<T, TValue>(this List<T> obj, TValue id, Func<T, TValue> value, Func<T, TValue> parent, Action<T, int> action, int depth = 0)
        {
            foreach (T t in obj.FindAll(m => parent.Invoke(m).Equals(id)))
            {
                action.Invoke(t, depth + 1);
                obj.GetTree(value.Invoke(t), value, parent, action, depth + 1);
            }
        }


    }
    /// <summary>
    /// 陣列過濾規則
    /// </summary>
    public enum ArrayFilterRule
    {
        /// <summary>
        /// 過濾重複
        /// </summary>
        NoRepeater
    }

    /// <summary>
    /// 插入陣列的位置
    /// </summary>
    public enum ArrayInjectPlace
    {
        /// <summary>
        /// 在頂部插入
        /// </summary>
        Top,
        /// <summary>
        /// 在尾部追加
        /// </summary>
        Bottom
    }
}

2、EnumExtensions.cs

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace EnumHelper
{
    /// <summary>
    /// 列舉擴充套件
    /// </summary>
    public static class EnumExtensions
    {
        private static ConcurrentDictionary<Enum, string> _concurrentDictionary = new ConcurrentDictionary<Enum, string>();
        private static ConcurrentDictionary<Type, Dictionary<string, string>> _concurrentDicDictionary = new ConcurrentDictionary<Type, Dictionary<string, string>>();
        /// <summary>
        /// 鎖物件
        /// </summary>
        private static object objLock = new object();

        /// <summary>
        /// 獲取列舉的描述資訊(Descripion)。
        /// 支援位域,如果是位域組合值,多個按分隔符組合。
        /// </summary>
        public static string GetDescription(this Enum @this)
        {
            return _concurrentDictionary.GetOrAdd(@this, (key) =>
            {
                var type = key.GetType();
                var field = type.GetField(key.ToString());
                //如果field為null則應該是組合位域值,
                return field == null ? key.GetDescriptions() : GetDescription(field);
            });
        }
        /// <summary>
        /// 獲取列舉的說明
        /// </summary>
        /// <param name="split">位列舉的分割符號(僅對位列舉有作用)</param>
        public static string GetDescriptions(this Enum em, string split = ",")
        {
            var names = em.ToString().Split(',');
            string[] res = new string[names.Length];
            var type = em.GetType();
            for (int i = 0; i < names.Length; i++)
            {
                var field = type.GetField(names[i].Trim());
                if (field == null) continue;
                res[i] = GetDescription(field);
            }
            return string.Join(split, res);
        }
        private static string GetDescription(FieldInfo field)
        {
            var att = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute), false);
            return att == null ? field.Name : ((DescriptionAttribute)att).Description;
        }

        /// <summary>
        /// 把列舉轉換成為列表
        /// </summary>
        public static List<EnumObject> ToList(this Type type)
        {
            List<EnumObject> list = new List<EnumObject>();
            foreach (object obj in Enum.GetValues(type))
            {
                list.Add(new EnumObject((Enum)obj));
            }
            return list;
        }

        /// <summary>
        /// 構造UTable列舉json樣式 eg.{"Resource":{"value":0,"name":"Resource","text":"自有資源"},"New":{"value":1,"name":"New","text":"業務費用"}}
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Dictionary<string, EnumModel> GetEnumList(this Type type)
        {
            Dictionary<string, EnumModel> list = new Dictionary<string, EnumModel>();
            foreach (object obj in Enum.GetValues(type))
            {
                list.Add(((Enum)obj).ToString(), new EnumModel((Enum)obj));
            }
            return list;
        }

        ///<summary>  
        /// 獲取列舉值+描述  
        ///</summary>  
        ///<param name="enumType">Type,該引數的格式為typeof(需要讀的列舉型別)</param>  
        ///<returns>鍵值對</returns>  
        public static Dictionary<string, string> GetEnumItemValueDesc(Type enumType)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            Type typeDescription = typeof(DescriptionAttribute);
            FieldInfo[] fields = enumType.GetFields();
            string strText = string.Empty;
            string strValue = string.Empty;
            foreach (FieldInfo field in fields)
            {
                if (field.FieldType.IsEnum)
                {
                    strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString();
                    object[] arr = field.GetCustomAttributes(typeDescription, true);
                    if (arr.Length > 0)
                    {
                        DescriptionAttribute aa = (DescriptionAttribute)arr[0];
                        strText = aa.Description;
                    }
                    else
                    {
                        strText = field.Name;
                    }
                    dic.Add(strValue, strText);
                }
            }

            return dic;


        }

        /// <summary>
        /// 獲取列舉型別鍵值對
        /// </summary>
        /// <param name="em"></param>
        /// <returns></returns>
        public static Dictionary<string, string> GetEunItemValueAndDesc(Type em)
        {
            return _concurrentDicDictionary.GetOrAdd(em, (key) =>
            {
                var type = key.GetType();
                if (_concurrentDicDictionary.ContainsKey(key))
                    return _concurrentDicDictionary[key];
                else
                    return GetEnumItemValueDesc(em);
            });
        }
        ///<summary>  
        /// 獲取列舉項+描述  
        ///</summary>  
        ///<param name="enumType">Type,該引數的格式為typeof(需要讀的列舉型別)</param>  
        ///<returns>鍵值對</returns>  
        public static Dictionary<string, string> GetEnumItemDesc(Type enumType)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            FieldInfo[] fieldinfos = enumType.GetFields();
            foreach (FieldInfo field in fieldinfos)
            {
                if (field.FieldType.IsEnum)
                {
                    Object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    dic.Add(field.Name, ((DescriptionAttribute)objs[0]).Description);
                }
            }
            return dic;
        }
        /// <summary>  
        /// 獲取列舉項描述資訊 例如GetEnumDesc(Days.Sunday)  
        /// </summary>  
        /// <param name="en">列舉項 如Days.Sunday</param>  
        /// <returns></returns>  
        public static string GetEnumDesc(this Enum en)
        {
            Type type = en.GetType();
            MemberInfo[] memInfo = type.GetMember(en.ToString());
            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (attrs != null && attrs.Length > 0)
                    return ((DescriptionAttribute)attrs[0]).Description;
            }
            return en.ToString();
        }

        /// <summary>
        /// 將註釋轉換成列舉值,匹配不上返回Null
        /// </summary>
        /// <param name="type"></param>
        /// <param name="strDescription"></param>
        /// <returns></returns>
        public static int? GetEnumValByDescription(this Type type, string strDescription)
        {
            int? enumVal = null;
            foreach (object obj in Enum.GetValues(type))
            {
                Enum nEnum = (Enum)obj;
                if (nEnum.GetDescription() == strDescription)
                {
                    enumVal = (int)Convert.ChangeType(nEnum, typeof(int));
                }
            }
            return enumVal;
        }
    }
}

 

3、EnumModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UUT.TeamCenter.Utility.EnumHelper
{
    public struct EnumModel
    {
        public EnumModel(Enum um)
        {
            this.value = (int)Convert.ChangeType(um, typeof(int));
            this.name = um.ToString();
            this.text = um.GetDescription();
        }
        public int value { get; set; }
        public string name { get; set; }
        public string text { get; set; }
    }
}

4、EnumObject.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UUT.TeamCenter.Utility.EnumHelper
{
    /// <summary>
    /// 列舉、型別的值
    /// </summary>
    public struct EnumObject
    {
        public EnumObject(Enum um, string picture = null)
        {
            this.ID = (int)Convert.ChangeType(um, typeof(int));
            this.Name = um.ToString();
            this.Description = um.GetDescription();
            this.Picture = picture;
        }

        public EnumObject(int id, string name)
        {
            this.ID = id;
            this.Name = this.Description = name;
            this.Picture = null;
        }

        public EnumObject(int id, string name, string description, string picture)
        {
            this.ID = id;
            this.Name = name;
            this.Description = description;
            this.Picture = picture;
        }

        public int ID;

        public string Name;

        public string Description;

        public string Picture;
    }
}

 

相關文章