天天看点

.NET Enum枚举公共类以及获取所有枚举项公共方法封装

项目中枚举是比较常用的一种类型,在功能开发的时候我们经常会获取所有的枚举项做一些逻辑判断,以及将每个枚举的所有枚举项传递给UI或者API等。为了解决获取枚举的所有枚举项,我们将枚举封装为枚举类EnumNode,并扩展获取所有枚举项的扩展方法ToSelectList,详细代码如下:

------------------------------------------------------EnumNode枚举项通用类---------------------------------------------------------

    /// <summary>

    /// 枚举通用类

    /// </summary>

    public class EnumNode

    {

        /// <summary>

        /// Id

        /// </summary>

        public int Id { get; set; }

        /// <summary>

        /// 文本值

        /// </summary>

        public string Value { get; set; }

        /// <summary>

        /// 名称

        /// </summary>

        public string Name { get; set; }

        /// <summary>

        /// 是否选中

        /// </summary>

        public bool Selected { get; set; }

    }

------------------------------------------------------EnumManager枚举管理类---------------------------------------------------------

    /// <summary>

    /// 枚举管理类

    /// </summary>

    public static class EnumManager

    {

        /// <summary>

        /// 获取枚举项列表

        /// </summary>

        /// <typeparam name="TEnum">枚举类型</typeparam>

        /// <param name="enumObj">枚举项</param>

        /// <param name="markCurrentAsSelected">是否选中当前枚举项</param>

        /// <param name="valuesToExclude">不包含的枚举项</param>

        /// <returns>通用枚举列表</returns>

        public static IList<EnumNode> ToSelectList<TEnum>(this TEnum enumObj,

           bool markCurrentAsSelected = true, int[] valuesToExclude = null) where TEnum : struct

        {

            IList<EnumNode> values = new List<EnumNode>();

            if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

            var enums = from TEnum enumValue in Enum.GetValues(typeof(TEnum))

                        where valuesToExclude == null || !valuesToExclude.Contains(Convert.ToInt32(enumValue))

                        select enumValue;

            foreach (var enumValue in enums)

            {

                var value = new EnumNode {

                    Id = Convert.ToInt32(enumValue),

                    Value = enumValue.ToString(),

                    Name = enumValue.ToString()

                };

                FieldInfo field = (typeof(TEnum)).GetField(enumValue.ToString());

                if (field != null) {

                    var attrs = field.GetCustomAttributes();

                    foreach (var attr in attrs)

                    {

                        var propertyName = attr.GetType().GetProperty("Name");

                        if (propertyName != null)

                        {

                            value.Name = propertyName.GetValue(attr).ToString();

                        }

                    }

                }

                if (markCurrentAsSelected && Convert.ToInt32(enumObj) == value.Id)

                {

                    value.Selected = true;

                }

                values.Add(value);

            }

            return values;

        }

    }

------------------------------------------------------项目调用---------------------------------------------------------

///前置代码...

var orderStatusItems = OrderStatusEnum.Pending.ToSelectList();

///后置代码...

扩展方法中我们通过反射来获取的Enum的显示名称Name,该值从CustomAttribute属性为Name的值获取(如下示例代码),CustomAttribute属性可以直接使用常用的DisplayAttribute(System.ComponentModel.DataAnnotations)或者自己扩展的属性,只要属性定义了Name成员即可被反射出来。

------------------------------------------------------枚举示例定义代码---------------------------------------------------------

    public enum OrderStatusEnum

    {

        [Display(Name = "待处理")]

        Pending = 10,

        [Display(Name = "已支付")]

        Paid = 20,,

    }

通过扩展方法我们可以直接获取所有定义的枚举的枚举项列表,解决了项目中获取所有枚举项的问题。

希望对应枚举的封装对于大家帮助,如果有什么问题或者反馈,也欢迎大家提出来!