Enum是如何用的?
一、前言
对于枚举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年过去了,人生如戏...
Enum是如何用的?的更多相关文章
- 关于Java中枚举Enum的深入剖析
在编程语言中我们,都会接触到枚举类型,通常我们进行有穷的列举来实现一些限定.Java也不例外.Java中的枚举类型为Enum,本文将对枚举进行一些比较深入的剖析. 什么是Enum Enum是自Java ...
- 如何用C代码生成二维码
如何用C代码生成二维码 当下因微信和支付宝等手机应用广泛使用,而基于二维码/一维条码的移动支付,也借助手机移动端席卷全国,使得越来越多的人知道有"二维码"这么一种东西. 对于普通用 ...
- 正确的使用枚举(Enum)
状态与选项的区别(states and options) 在用enum之前,我个人觉得,区分一下状态和选项的概念还是很必要的. 状态,同时只能有一种,如“OK”,“Error”,不可能同时是OK和Er ...
- Android中是否推荐使用枚举Enum
一.Enum的产生 Java1.5中引入了枚举的语法,包括Enum,EnumSet,EnumMap等.其中Enum就是我们在C或C++中见过的枚举类型,但是Java中的枚举又比C或C++中的枚举更成熟 ...
- 面试题之发散思维能力:如何用非常规方法求1+2+···+n
今天在<剑指offer>里看到了下面这样一个简单且有趣的题,考察程序员的发散思维能力,前提是你对C++相关知识点熟悉,否则是想不出来方案的,分享给大家. 题目:求1+2+···+n,要 ...
- 如何用FFmpeg API采集摄像头视频和麦克风音频,并实现录制文件的功能
之前一直用Directshow技术采集摄像头数据,但是觉得涉及的细节比较多,要开发者比较了解Directshow的框架知识,学习起来有一点点难度.最近发现很多人问怎么用FFmpeg采集摄像头图像,事实 ...
- ios高效开发-正确的使用枚举(Enum)
前言 Enum,也就是枚举,从C语言开始就有了,C++.Java.Objective-C.Swift这些语言,当然都有对应的枚举类型,功能可能有多有少,但是最核心的还是一个—规范的定义代码中的状态.选 ...
- 剖析:如何用 SwiftUI 5天组装一个微信 —— 通讯录发现我篇
前置资源 GitHub: SwiftUI-WeChatDemo 第零章:用 SwiftUI 5天组装一个微信 第一章:剖析:如何用 SwiftUI 5天组装一个微信 -- 聊天界面篇 通讯录 通讯录的 ...
- Swift enum(枚举)使用范例
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
随机推荐
- LVM增大和减小ext4、xfs分区
可以对ext4调整分区大小,能自动识别要增大还是减小 lvresize -L 300M -r /dev/vg/lvol0 原文地址http://www.361way.com/lvm-xfs-ext4/ ...
- 准备开发一款开源NES模拟器
前几天无意见看到一些NES的开发资料,勾起了小时候暑假的无数美好回忆,做为一名码农,萌发了自己写一款模拟器的想法.一来可以加深自己对整个系统/游戏的理解,一来可以实现小时候的梦想:),希望可以坚持下来 ...
- vim符号列表窗口
有时使用vim开发时,需要能够直观的查看文件的符号列表或者变量list,但是vim不直接支持这个功能,需要使用ctags的插件支持. 以下是在ubuntu下的详细设置方法: 步骤1:安装ctags u ...
- spring boot分布式技术,spring cloud,负载均衡,配置管理器
spring boot分布式的实现,使用spring cloud技术. 下边是我理解的spring cloud的核心技术: 1.配置服务器 2.注册发现服务器eureka(spring boot默认使 ...
- js和php对bool值的判断区别
一.将一种数据类型转换为bool值时,PHP和JS的转换规则不同 PHP中 当转换为 boolean 时,以下值被认为是 FALSE : 布尔值 FALSE 本身 整型值 0(零) 浮点型值 0.0( ...
- Ceph剖析:Leader选举
作者:吴香伟 发表于 2014/09/11 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 Paxos算法存在活锁问题.从节点中选出Leader,然后将所有对数据 ...
- hibernate常用关联
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns=" ...
- Spring知识点总结大全(2)
3.Spring的AOP 一.AOP(Aspect-oriented programming,面向切面编程): 什么是AOP? 定义:将程序中的交叉业务逻辑提取出来,称之为切面.将这些切面动态织入到目 ...
- error C2664
error C2664: “int CWnd::MessageBoxW(LPCTSTR,LPCTSTR,UINT)”: 无法将参数 1 从“const char [19]”转换为“LPCTSTR” n ...
- OS 系统下安装MySql 配置MySql环境变量
学习Hive需要,闲话不说 本文的内容: 下载Mysql for Mac 下载Mysql Workbench 安装 Mysql 和 Mysql Workbench 配置Mysql在OS 系统上的环境变 ...