枚举是由程序员定义的类型与类或结构一样。
与结构一样,枚举是值类型,因此直接存储它们的数据,而不是分开存储成引用和数据
枚举只有一种类型的成员:命名的整数值常量
例:枚举示例
关键字 枚举名称 ↓ ↓ enum TrafficLight { Green, ← 逗号分隔,没有分号 Yellow, Red }
每个枚举类型都有一个底层整数类型,默认为int。
每个枚举成员都被赋予一个底层类型的常量值
在默认情况下,编译器把第一个成员赋值为0,并对每个后续成员赋的值比前一个多1
var t1=TrafficLight.Green; var t2=TrafficLight.Yellow; var t3=TrafficLight.Red; Console.WriteLine("{0},\t{1}",t1,(int)t1); Console.WriteLine("{0},\t{1}",t2,(int)t2); Console.WriteLine("{0},\t{1}",t3,(int)t3);
设置底层类型和显式值可以把冒号和类型名放在枚举名之后,这样就可以使用int以外的整数类型。类型可以是任何整数类型。所有成员常量都属于枚举的底层类型。
enum TrafficLight:ulong { ... }
成员常量的值可以是底层类型的任何值。枚举成员不能有重复的名称,但可以有重复的值。
enum TrafficLight { Green =10, Yellow =15, Red =15 }
隐式成员编号如果不初始化一个成员常量,编译器隐式给它赋一个值。
例:
enum CardSuit { Hearts, //0 因为这是第一项 Clubs, //1 比之前大1 Diamonds, //2 比之前大1,下面的以此类推 Spades, MaxSuits } enum FaceCards { //Member //所赋的值 Jack =11, //11 显式设置 Queen, //12 比之前大1 King, //13 比之前大1 Ace, //14 比之前大1 NumberOfFaceCards=4, //4 显式设置 SomeOtherValue, //5 比之前大1 HighestFaceCard=Ace //14 以上定义了Ace }
位标志程序员们长期使用单个字(single word)的不同位作为一组开/关标志的紧凑方法。本节将其称为标志字(flag word)。枚举提供了实现它的简便方法。
一般步骤如下。
确定需要多少个位标志,并选择一个有足够多位的无符号类型来保存它
确定每个位位置代表声明,并给它们名称。声明一个选中的整数类型枚举,每个成员由一个位位置表示
使用按位或(OR)运算符设置保持该位标志的字中的适当的位
使用按位与(AND)运算符,或HasFlag方法解开位标志
例:下面枚举表示纸牌游戏中的一副牌的选项。
成员有表示二进制选项的名称
每个选项由字中的一个特殊的位表示,位位置保持一个0或一个1
因为一个位标志表示一个或开或关的位,所以你不会想用0作为一个成员值。它已经有了一个意思:所有的位标志都是关
在16进制表示法中,每个16机制数字用4位来表示。由于位模式和16进制表示法之前的联系,所以在处理位模式时,常使用16进制而不是10进制
使用Flags特性装饰(decorate)枚举实际上不必要,但可以有一些额外的便利,很快会讨论这一点。特性表现为用中括号括起来的字符串,出现在语言构造之前。在本例中,特性出现在枚举声明之前。特性在第24章阐述
[Flags] enum CardDeckSettings:uint { SingleDeck =0x01, //位0 LargePictures =0x02, //位1 FancyNumbers =0x04, //位2 Animation =0x08 //位3 }
要创建一个带有适当位标志的字,需要声明一个该枚举类型的变量,并使用按位或运算符设置需要的位。
CardDeckSettings ops= CardDeckSettings.SingleDeck |CardDeckSettings.FancyNumbers |CardDeckSettings.Animation;