首页 技术 正文
技术 2022年11月9日
0 收藏 920 点赞 2,119 浏览 4793 个字

一、前言

对于枚举Enum,大家都非常熟悉,但枚举出现的场景非常多的时候,是不是可以抽象出一个通用的解决方式。代码大家都会写,但并不是所有人都喜欢写重复的代码,老是用Ctrl+C和Ctrl+V累不累啊?很多人和我一样,非常不喜欢写重复的代码,代码写多了,BUG就多。对于常见的场景,大部分人都喜欢抽象出来,写一套通用的,每个地方都可以用,而且不易出错。当然,你喜欢Ctrl+C和Ctrl+V,本人也没有办法….

二、int值,string值转换成Enum

如下,一个简单枚举:

    public enum ExchangeType
{
[EnumFieldAttribute("不限", true)]
All = ,
[EnumFieldAttribute("深圳证券交易所")]
SZSE =
}

对于以下输入代码:

            ExchangeType type = (ExchangeType);            if (type == ExchangeType.All)
{
Console.WriteLine("ExchangeType.All.");
}
else if (type == ExchangeType.SZSE)
{
Console.WriteLine("ExchangeType.SZSE.");
}
else
{
Console.WriteLine("Non Exist!");
}

对于强制转换,大家猜猜看,会输出什么….

对于结果,大家可以自己去测试下,有可能与你期望的值不一致!

同样对于以下代码:

ExchangeType type;
bool success = Enum.TryParse<ExchangeType>("", out type);

TryParse执行的返回结果success也是成功的(为true),但期望值也不一定正确。

因此,对于枚举转换来说,还是很容易出错的。所以,必须提供默认的值来确保转换失败时,返回正确的值。对于int值和string值转换成Enum的代码如下:

        public static T ToEnum<T>(int value, T defaultT) where T : struct
{
string enumName = Enum.GetName(typeof(T), value); return ToEnum<T>(enumName, defaultT);
} public static T ToEnum<T>(string enumName, T defaultT) where T : struct
{
if (string.IsNullOrWhiteSpace(enumName))
{
return defaultT;
} T result; if (!Enum.TryParse<T>(enumName.Trim(), out result))
{
return defaultT;
} if (Enum.IsDefined(typeof(T), result))
{
return result;
} return defaultT;
}

另外还提供了其他应用的方法,如将包含类型名称前缀的字符串ExchangeType.All转换成枚举,同样需要提供默认值来确保转换结果的准确性,代码如下:

        public static T TryParse<T>(string typeValue, T defaultValue, bool containsTypeName = false) where T : struct
{
typeValue = (typeValue ?? string.Empty).Trim(); if (containsTypeName)
{
int startIndex = typeValue.IndexOf("."); if (startIndex > && typeValue.Length > startIndex + )
{
typeValue = typeValue.Substring(startIndex + );
}
} return ToEnum<T>(typeValue, defaultValue);
}

应用的话,比较简单,ExchangeType type = EnumFieldProvider.TryParse<ExchangeType>(“ExchangeType.”, ExchangeType.All, true);

三、高级应用通用方式

对于下拉列表中,很多场景与枚举有关,硬编码也可以直接绑定。但是枚举很多的时候是不是得写很多代码,而且并不一定保证代码的正确性。与其这样,那就写一个通用的吧,大家都轻松:

        public static EnumFieldAttribute GetEnumAttribute(Type type)
{
if (type == null)
{
return null;
} object[] customAttributes = type.GetCustomAttributes(typeof(EnumFieldAttribute), true);
EnumFieldAttribute attribute = null; foreach (object attr in customAttributes)
{
attribute = attr as EnumFieldAttribute; if (attribute != null)
{
return attribute;
}
} return null;
} public static IList<EnumItem<T>> GetItems<T>(bool isSpecialRequired = false) where T : struct
{
var fields = typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public); if (fields == null || fields.Count() == )
{
return new List<EnumItem<T>>();
} var enumItems = new List<EnumItem<T>>();
EnumFieldAttribute attribute = null;
T currentValue; foreach (var field in fields)
{
object[] customAttributes = field.GetCustomAttributes(typeof(EnumFieldAttribute), true);
foreach (object attr in customAttributes)
{
attribute = attr as EnumFieldAttribute; if (attribute != null)
{
if (attribute.IsSpecialRequired)
{
if (!isSpecialRequired)
{
continue;
}
} currentValue = (T)field.GetValue(null); enumItems.Add(new EnumItem<T>(currentValue, attribute.Desc));
}
}
} return enumItems;
} public static IList<EnumItem<T>> GetItems<T>(IList<T> entities) where T : struct
{
if (entities == null || entities.Count() == )
{
return new List<EnumItem<T>>();
} var enumItems = new List<EnumItem<T>>(); foreach (var entity in entities)
{
enumItems.Add(GetItem<T>(entity));
} return enumItems;
} public static string GetItemDescription<T>(T enumItem) where T : struct
{
var field = typeof(T).GetField(enumItem.ToString()); if (field == null)
{
return string.Empty;
} object[] customAttributes = field.GetCustomAttributes(typeof(EnumFieldAttribute), true);
foreach (object attr in customAttributes)
{
EnumFieldAttribute attribute = attr as EnumFieldAttribute; if (attribute != null)
{
return attribute.Desc;
}
} return string.Empty;
} public static EnumItem<T> GetItem<T>(T enumItem) where T : struct
{
var field = typeof(T).GetField(enumItem.ToString()); if (field == null)
{
return new EnumItem<T>(enumItem, enumItem.ToString());
} object[] customAttributes = field.GetCustomAttributes(typeof(EnumFieldAttribute), true);
foreach (object attr in customAttributes)
{
EnumFieldAttribute attribute = attr as EnumFieldAttribute; if (attribute != null)
{
return new EnumItem<T>(enumItem, attribute.Desc);
}
} return new EnumItem<T>(enumItem, enumItem.ToString());
}

对于方法public static IList<EnumItem<T>> GetItems<T>(bool isSpecialRequired = false) where T : struct,提供一个参数来筛选是否需要该参数,如以上定义的枚举类型ExchangeType中的 EnumFieldAttribute(“不限”, true),其中EnumFieldAttribute(“不限”, true)第二个参数与isSpecialRequired参数一致。
测试代码如下:

        [TestMethod()]
public void GetItemsTest()
{
IList<EnumItem<ExchangeType>> actual = EnumFieldProvider.GetItems<ExchangeType>(true);
Assert.AreEqual(actual.Count, );
Assert.AreEqual(actual[].Value, ExchangeType.All);
Assert.AreEqual(actual[].Value, ExchangeType.SZSE);
} [TestMethod()]
public void GetItemsWithFalseArgTest()
{
IList<EnumItem<ExchangeType>> actual = EnumFieldProvider.GetItems<ExchangeType>();
Assert.AreEqual(actual.Count, );
Assert.AreEqual(actual[].Value, ExchangeType.SZSE);
}

返回的结果可以用于下拉列表,ListBox等相关控件值的绑定与显示(由于明天还得上班,本文不提供,下篇随笔提供)。

四、总结

对于细节方面,还是需要花时间和精力来总结的。用得多了,自然也就懂了,洗洗睡觉了…

今天又是7月1号,又是一个纪念日。4年前,6月26号毕业联欢晚会后,哥开始正式工作的第一天也是7月1号。一转眼,4年过去了,人生如戏…

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,088
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,564
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,413
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,186
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,822
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,905