本篇总结来自于一个小小的开发需求,即给枚举一个中文名称,一般来说不推荐(或者有更加严格的说法是不予许)在代码中使用中文,那么有时候需要在界面上展示中文,怎么弄?贴标签,反射获取即可,网上的代码一堆哦(下面也会给出)。从这个不定点的开发需求出发,我将这个毫不起眼的Enum进行了总结,本篇不在传道解惑,意在温故知新,方便日后翻阅,若文中有瑕疵纰漏之处,请留言当面指正,不必留情。
public enum Week
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
就这么用了,没什么特殊需求啊
(1)问题1:关于枚举的默认值
public enum Week
{
Monday,
Tuesday=0,//默认值
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
Week week_today = Week.Monday;
Console.WriteLine(week_today == 0);
Console.WriteLine(week_today);
Console.WriteLine((Week)2);
Console.ReadKey();
[Flags]
public enum Week
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
给枚举贴上一个[Flags]特性标签,那么枚举变量可以进行位操作,一般用来取多个值,看看下面的两个Demo:
//周末
Week weekend = Week.Saturday | Week.Sunday;
Console.WriteLine(weekend);
//健身
Week workout = Week.Monday | Week.Tuesday;
Console.WriteLine(workout);
Console.ReadKey();
操,什么情况?周末weekend输出的是两天,但是这两天不对啊,workout干脆就是一天了,Monday哪儿去了啊?带着这些问题查了一下[Flags]的位操作,原来是这样啊!
符号 | 描述 | 运算规则 |
---|---|---|
& | 与 | 1与1等于1,1与0等于0,0与0等于0 |
| | 或 | 1或1等于1,1或0等于1,0或0等于0 |
^ | 异或 | 相同得0,相异得1 |
~ | 取反 | 如果某一位等于0,就将其转变为1;如果某一位等于1,就将其转变为0 |
<< | 左移 | 位左移运算将整个数按位左移若干位,左移后空出的部分0 |
>> | 右移 | 位右移运算将整个数按位右移若干位,右移后空出的部分填0 |
说明:默认情况下上面的枚举值依次为0,1,2,3,4,5,6,不妨先看看Week.Monday | Week.Tuesday,转为二进制(仅仅列出四位)即是0000|0001=0001,所以结果显示1所对应的Tuesday,而Week.Saturday | Week.Sunday,即是0101|0110=0111(7),将这个复合值分解的时候,分解成了Tuesday(1)和Sunday(6),这里为什么这样分解?而不是分解成3和4或者2和5,我并没有搞懂,有知道的大神可以留言回复。那么怎么解决存在复合值的问题呢?MSDN:在 2 的幂,即 1、 2、 4、 8 等中定义枚举常量。 这意味着不重叠中组合的枚举常量的各个标志。因此你常见的一些写法就出来了:
/*直接二进制,简单易理解*/
[Flags]
public enum Week
{
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64
}
/*左移操作的结果是一样的,00000001把1的值一直往左移动*/
[Flags]
public enum Week
{
Monday = 1,
Tuesday = 1<<1,
Wednesday = 1<<2,
Thursday = 1<<3,
Friday = 1<<4,
Saturday = 1<<5,
Sunday = 1<<6
}
/*16进制表示*/
[Flags]
public enum Week
{
Monday = 0x01,
Tuesday = 0x02,
Wednesday = 0x04,
Thursday = 0x08,
Friday = 0x10,
Saturday = 0x20,
Sunday = 0x40
}
上述的三种表示方法均可,我进本上采用的是直接用整型表示,这里有一点需要注意的是2n(n>=0),上面的示例已经说明了0|1=1,因此不要把0包含进来,我看到网上的很多示例中都有包含0,这实际上是不对的。关于位复合枚举的操作,常用的还有如下操作:判断存在,剔除,添加,看看Demo(具体的位操作就不解释了,有兴趣的可以深入了解)
Week weekday = Week.Monday | Week.Tuesday | Week.Wednesday | Week.Thursday | Week.Friday;
Console.WriteLine("原始:"+weekday);
//判断是否包含枚举值
bool isContains = (weekday & Week.Friday) == Week.Friday;
//剔除枚举值
if (isContains)
weekday = weekday & ~Week.Friday;
Console.WriteLine("剔除之后:" + weekday);
//添加枚举值
weekday = weekday | Week.Friday;
Console.WriteLine("添加之后:" + weekday);
Console.ReadKey();
(3)问题3:关于枚举的中文描述
[Flags]
public enum Week
{
[Description("星期一")]
Monday = 1,
[Description("星期二")]
Tuesday = 2,
[Description("星期三")]
Wednesday = 4,
[Description("星期四")]
Thursday = 8,
[Description("星期五")]
Friday = 16,
[Description("星期六")]
Saturday = 32,
[Description("星期日")]
Sunday = 64
}
主要是为了方便在使用的时候,尤其是在UI界面上展示时需要用到中文,看看下面的Demo:
public static class EnumHelper
{
///
/// 反射获取Description
///
///
///
public static string GetDescription(this Enum enumName)
{
string description = string.Empty;
FieldInfo fieldInfo = enumName.GetType().GetField(enumName.ToString());
if (fieldInfo == null) return enumName.ToString();
DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
description = attributes[0].Description;
else
description = enumName.ToString();
return description;
}
///
/// Description转Enum
///
///
///
///
public static T GetEnumByDescription(string description)
{
Type type = typeof(T);
if (!type.IsEnum) throw new Exception("当前不是枚举类型!");
DescriptionAttribute[] attributes = null;
foreach (FieldInfo fieldInfo in type.GetFields())
{
if (fieldInfo == null) continue;
attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
if (attributes[0].Description == description)
return (T)fieldInfo.GetValue(null);
}
else
{
if (fieldInfo.Name == description)
return (T)fieldInfo.GetValue(null);
}
}
throw new ArgumentException("未能找到对应的枚举值:" + description);
}
///
/// 获取枚举集合
///
///
///
///
public static Dictionarystring> EnumToArrayList(this Type type)
{
if (type.IsEnum)
{
Dictionarystring> result = new Dictionarystring>();
Array _enumValues = Enum.GetValues(type);
foreach (Enum value in _enumValues)
{
result.Add(value, GetDescription(value));
}
return result;
}
return null;
}
}
/*测试代码*/
Week week_today = Week.Monday;
Console.WriteLine(week_today.GetDescription());
Week week_test = EnumHelper.GetEnumByDescription("星期五");
Console.WriteLine(week_test);
Dictionary result = typeof(Week).EnumToArrayList();
Console.WriteLine(result[Week.Thursday]);