谈谈对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 }
结束:
以上测值的结果值,我就不贴了,就当留给你们亲手实践的作业吧。