软件开发中,最离不开的就是枚举的使用了,比如:用户状态管理,用户权限管理等。凡是用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
}
以上测值的结果值,我就不贴了,就当留给你们亲手实践的作业吧。
原文:https://www.cnblogs.com/yuyoho/p/13268053.html