枚举是一种值类型,用于定义一组具有特定名称和数值的常量。
枚举可以用于表示有限的可选项,例如中国的56个民族,或者扑克牌的花色。
枚举使用关键字enum
声明,后跟枚举类型的名称和成员列表。
枚举成员只能是字段,不能包含其他成员类型。
字段声明只需要写标识符,不能写类型、访问修饰符或赋值符号。
enum Suit // 花色
{
Spade, // 黑桃
Heart, // 红心
Diamond, // 方块
Club // 梅花
}
枚举成员的数值绑定是指将每个成员与一个整数值相关联。
这样可以方便地将枚举与数字进行转换和比较。
枚举成员的类型默认为int
,也可以显式指定为其他整数类型。
数值绑定可以显式指定,在字段声明后面加上等号和一个整数常量表达式。
隐式推断遵循以下规则:
数值绑定可以出现重复或无序的情况,但这可能会导致混淆或错误。
enum Weekday : int // 星期
{
Monday = 1, // 星期一
Tuesday = 2, // 星期二
Wednesday = 3, // 星期三
Thursday = 4, // 星期四
Friday = 5, // 星期五
Saturday = 6, // 星期六
Sunday = 7 // 星期日
}
位枚举是一种特殊的枚举,用于表示多个独立的布尔标志,可以使用位运算符进行组合或分解。
位枚举通常将每个成员的数值绑定为2的整数次幂,
这样可以保证每个成员只占用一个二进制位,并且不会与其他成员重叠。
位枚举可以使用[Flags]
特性标记,他实例的ToString
方法,会输出这些组成成员用逗号分隔的列表。
[Flags]
enum Position // 职位
{
Founder = 0b1, // 创始人
ViceLeader = 0b10, // 副首领
Builder = 0b100, // 建造师
Promoter = 0b1000, // 宣传师
Recruiter = 0b10000, // 招聘者
Cleaner = 0b100000, // 整治者
Researcher = 0b1000000, // 研究者
}
要访问枚举成员,直接使用类型名访问他的成员。
Card Card = new Card();
Card.Suit = Suit.Spade;
Card.Rank = 4;
public class Card
{
public Suit Suit;
public int Rank;
}
使用位枚举,可以使用位运算符进行组合或分解。
位或运算符|
可以将多个位枚举成员合并为一个值,表示同时具有这些成员的标志。
位与运算符&
可以将一个位枚举值与另一个值进行比较,判断是否包含某个成员的标志。
Position CarpDragon = Position.Founder | Position.Recruiter;
// 职位 暴鲤龙 = 职位.创始人 | 职位.招聘者;
if ((CarpDragon & Position.Recruiter) == Position.Recruiter)
{
Console.WriteLine("成员暴鲤龙具有招聘权限");
}
else
{
Console.WriteLine("成员暴鲤龙禁止招聘");
}
实例方法HasFlag
封装了使用位与运算符判断是否包含某个标志的逻辑,可以简化代码的编写。但是,如果枚举中存在0或其他特殊值,可能会导致意外的结果。
Position Sunflower = Position.Founder | Position.Recruiter;
// 职位 向日葵 = 职位.创始人 | 职位.招聘者;
if (Sunflower.HasFlag(Position.Recruiter))
{
Console.WriteLine("成员向日葵具有招聘权限");
}
else
{
Console.WriteLine("成员向日葵禁止招聘");
}
要将枚举值和数字值进行转换,可以使用强制类型转换。强制类型转换可以将一个枚举值转换为其对应的数值类型,或者将一个数值类型转换为其对应的枚举值。
枚举值和数字值之间可以进行算术运算,例如加减法。
但是,这可能会导致超出枚举定义范围的结果,或者破坏枚举的语义。
Weekday weekday = (Weekday)7;
Console.WriteLine((int)weekday > 3);
Console.WriteLine(weekday - 3);