谈谈对Enum的使用

前言:

  软件开发中,最离不开的就是枚举的使用了,比如:用户状态管理,用户权限管理等。凡是用bool值不能满足需求时,都可以枚举值来定义,既方便,又好用。还省心。既然有这么多好处,为什么不使用呢

正文:

我们准备如下的枚举定义,以下测试的整个过程中,都会使用到如下的枚举类:

/// <summary>
/// user state enum
/// </summary>
public enum UserState
{
    /// <summary>
    /// 在线
    /// </summary>
    [Description("在线")]
    Online,

    /// <summary>
    /// 离线
    /// </summary>
    [Description("离线")]
    Offline,

    /// <summary>
    /// 已删除
    /// </summary>
    [Description("已删除")]
    Deleted
}

  

  

通过枚举值Value获取枚举Name

//获取枚举Name
var enumName = Enum.GetName(typeof(UserState), 1);
// enumName = Offline

  

通过GetValues获取枚举值列表  

var enumValues = Enum.GetValues(typeof(UserState));

//enumValues值如下:
{BitwiseDemo.UserState[3]}
    [0]: Online
    [1]: Offline
    [2]: Deleted

通过如下方式获取值
for (int i = 0; i < enumValues.Length; i++)
{
    var value = enumValues.GetValue(i);
} 

  

通过GetNames获取枚举的字符串值

var enumNames = Enum.GetNames(typeof(UserState));

//enumNames值如下:
{string[3]}
    [0]: "Online"
    [1]: "Offline"
    [2]: "Deleted"

  

有时候,需要判断值是不是在定义的枚举范围内,可以使用IsDefined来进行判断

var isDefine = Enum.IsDefined(typeof(UserState), 3);
//isDefine = false

   

一下是封装过的枚举扩展类EnumExtension.cs,方便我们平时在调用过程中使用

    public static class EnumExtension
    {
        class EnumCache : ReaderWriterCache<Type, Dictionary<long, EnumItem>>
        {
            public Dictionary<long, EnumItem> GetEnumMap(Type t, Creator<Dictionary<long, EnumItem>> cr)
            {
                return FetchOrCreateItem(t, cr);
            }
        }
        #region 私有成员
        static readonly EnumCache Instance = new EnumCache();

        static Dictionary<long, EnumItem> FetchOrCreateEnumMap(Type t)
        {
            return Instance.GetEnumMap(t, () => CreateEnumMap(t));
        }
        static Dictionary<long, EnumItem> CreateEnumMap(Type t)
        {
            Dictionary<long, EnumItem> map = new Dictionary<long, EnumItem>();
            FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.Static);

            foreach (FieldInfo f in fields)
            {
                long v = Convert.ToInt64(f.GetValue(null));
                DescriptionAttribute[] ds = (DescriptionAttribute[])f.GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (ds.Length > 0)
                {
                    map[v] = new EnumItem { Value = v, Name = f.Name, Description = ds[0].Description };
                }
            }
            return map;
        }


        #endregion

        /// <summary>
        /// 返回该枚举类型的所有枚举项成员以及描述 
        /// </summary>
        /// <returns></returns>
        public static List<EnumItem> GetTypeItemList<EnumType>()
        {
            Type t = typeof(EnumType);
            return FetchOrCreateEnumMap(t).Values.ToList();
        }

        /// <summary>
        ///返回单枚举值的描述信息
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum v)
        {
            Type t = v.GetType();
            var map = FetchOrCreateEnumMap(t);

            if (map.TryGetValue(Convert.ToInt64(v), out var item))
            {
                return item.Description;
            }

            return string.Empty;
        }

        /// <summary>
        /// 从枚举名称转换成枚举类型
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public static T GetEnumType<T>(string name)
        {
            try
            {
                if (string.IsNullOrEmpty(name))
                {
                    return default(T);
                }
                return (T)System.Enum.Parse(typeof(T), name);
            }
            catch (Exception)
            {
                return default(T);
            }
        }

        /// <summary>
        /// 检查枚举值是否存在
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsDefined<T>(this object obj)
        {
            return Enum.IsDefined(typeof(T), obj);
        }

        /// <summary>
        /// 根据enumName 获取 value
        /// </summary>
        /// <param name="enumType"></param>
        /// <param name="enumName"></param>
        /// <returns></returns>
        public static int GetEnumValue<T>(this string enumName)
        {
            try
            {
                if (string.IsNullOrEmpty(enumName))
                {
                    return -1;
                }
                var values = Enum.GetValues(typeof(T));
                var ht = new Hashtable();
                foreach (var val in values)
                {
                    ht.Add(Enum.GetName(typeof(T), val), val);
                }
                return (int)ht[enumName];
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }

  

以下是使用到的Cache类 ReaderWriterCache.cs 文件类

public abstract class ReaderWriterCache<TKey, TValue> {
        /// <summary>
        /// 创建数据选择性的将其缓存
        /// </summary>
        /// <typeparam name="T">数据的类型</typeparam>
        /// <param name="cacheResult">是否缓存数据</param>
        /// <returns></returns>
        public delegate T CreatorOrCache<T>(out bool cacheResult);
        /// <summary>
        /// 创建数据
        /// </summary>
        /// <typeparam name="T">数据的类型</typeparam>
        /// <returns></returns>
        public delegate T Creator<T>();
        private readonly ReaderWriterLockSlim _rwLockSlim = new ReaderWriterLockSlim();

        protected ReaderWriterCache()
            : this(null) {
        }

        protected Dictionary<TKey, TValue> Cache { get; }
        protected ReaderWriterCache(IEqualityComparer<TKey> comparer) {
            Cache = new Dictionary<TKey, TValue>(comparer);
        }

        /// <summary>
        /// 如果存在则返回原来的数据否则就创建并且将其缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="creator"></param>
        /// <returns></returns>
        protected TValue FetchOrCreateItem(TKey key, CreatorOrCache<TValue> creator) {

            _rwLockSlim.EnterReadLock();
            try {
                TValue existingEntry;
                if (Cache.TryGetValue(key, out existingEntry)) {
                    return existingEntry;
                }
            } finally {
                _rwLockSlim.ExitReadLock();
            }

            bool cache;
            TValue newEntry = creator(out cache);
            //如果需要缓存
            if (cache) {
                _rwLockSlim.EnterWriteLock();
                try {
                    TValue existingEntry;
                    if (Cache.TryGetValue(key, out existingEntry)) {
                        return existingEntry;
                    }

                    Cache[key] = newEntry;

                } finally {
                    _rwLockSlim.ExitWriteLock();
                }
            }
            return newEntry;
        }

        /// <summary>
        /// 如果存在则返回原来的数据否则就创建并且将其缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="creator"></param>
        /// <returns></returns>
        protected TValue FetchOrCreateItem(TKey key, Creator<TValue> creator) {
            return FetchOrCreateItem(key, (out bool b) => {
                b = true;
                return creator();
            });
        }
    }

  

封装类中,使用到的枚举类如下:

    public class EnumItem {
        /// <summary>
        /// 枚举值
        /// </summary>
        public long Value { get; internal set; }
        /// <summary>
        /// 枚举名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 枚举的描述
        /// </summary>
        public string Description { get; internal set; }
    }

  

以下代码是调用示例:

private void EnumExtensionUse()
{
    //获取枚举列表(name value description)
    var getenumList = EnumExtension.GetTypeItemList<UserState>();

    //获取枚举描述
    var getDescription = ((UserState)UserState.Online).GetDescription();

    //通过name 获取value值
    var getValueByName = EnumExtension.GetEnumValue<UserState>("Online");

    //检查值是否在枚举中定义
    var value = 4;
    var checkEnumValue = value.IsDefined<UserState>();
   //checkEnumValue : false //将string name 转枚举 var enumItem = EnumExtension.GetEnumType<UserState>("Online");
   //enumItem :Online -- 枚举类型的Online }

结束:  

  以上测值的结果值,我就不贴了,就当留给你们亲手实践的作业吧。

  

posted @ 2020-07-08 17:32  yuyoho  阅读(207)  评论(0编辑  收藏  举报