zoukankan      html  css  js  c++  java
  • 谈谈对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 }

    结束:  

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

      

  • 相关阅读:
    量化投资_期货日内交易几个问题的考证
    量化投资_上一个交易时间段对今日收盘价涨跌的影响
    RunJS
    sublime3快捷 输入html
    NLP学习资源
    Invert Binary Tree
    定时任务 Crontab命令 详解
    根据职位名,自动生成jd
    使用python + tornado 做项目demo演示模板
    Awk 实例
  • 原文地址:https://www.cnblogs.com/yuyoho/p/13268053.html
Copyright © 2011-2022 走看看