12 枚举--C#

1.枚举

枚举是由程序员定义的类型,与结构一样。

枚举是值类型,直接存储它们的数据,不是分开存储成引用和数据。

枚举只是一种类型的成员:命名的整数值常量。成员声明之间逗号分隔。

例如:

enum TrafficLight

{

        Green,

        Yellow,

        Red

   }

使用关键字enum声明,后加枚举名称 TrafficLight,枚举值之间逗号分隔,枚举值使用大括号包裹。

每个枚举值默认为int.编译器对第一个成员赋值为0,后续每个成员赋值都比前一个多1.

测试:

Console.WriteLine($"{TrafficLight.Green}--{(int)TrafficLight.Green}");

输出:Green--0


Console.WriteLine($"{TrafficLight.Yellow}--{(int)TrafficLight.Yellow}");

Yellow--1


可把枚举值赋值给枚举类型变量。

TrafficLight TL = TrafficLight.Green;

 TrafficLight TL2 = TL;

Console.WriteLine($"{TL2} --{(int)TL2}");

输出:Green --0


设置底层类型和显示值

类型可以是任何整数类型。尽管不能有重复名称,但是可以有重复值。

//等效

    enum TrafficLight:int

    {

        Green =0,

        Yellow =1,

        Red=2

    }


也可以自定义值:

enum TrafficLight:int

    {

        Green =1,

        Yellow =3,

        Red=5

    }


给隐式成员编号

可显式给任何成员变量赋值,如果不初始化成员常量,编译器隐式给它赋初值。

enum Level

    {

        One =10,

        Two,

        Three=15,

        Four,

        Five=1

    }


测试:

Console.WriteLine($"{(int)Level.One} {(int)Level.Two} {(int)Level.Three} {(int)Level.Four} {(int)Level.Five}");

输出:10 11 15 16 1

从输出可以看出,可任意给枚举成员变量指定整型值,其后的变量值自动加1,指定的值是可以跳变的,也可以默认。


2.位标志

单个字Single word的不同位表示一组开关标志的紧凑方法。成为标志字 flag word.

一般步骤:

(1) 确定需要多少个标志位,选择一种有足够多的位的无符号类型来保存它。

(2) 确定每个位位置代表什么,并给它们一个名称。

(3) 使用按位或OR 运算符在持有该标志位的字中设置适当的位

(4) 使用按位与 AND运算符或HasFlag方法检查是否设置了特定位标志


从C# 7.0开始,可以使用二进制表示法

使用Flags特性可带来一些便利。

[Flags]

    enum CardSettings:uint

    {

        SingleDeck    = 0x01,

        LargePictures = 0x02,

        FancyNumbers  = 0x04,

        Aniamation    = 0x08

    }

测试代码:

CardSettings settings = CardSettings.SingleDeck | CardSettings.LargePictures;

 Console.WriteLine($"{settings} {(uint)settings}"); //输出:3

使用Flags 属性的标志枚举变量可以使用逻辑位运算。


如果指定的标志位有值返回true,否则返回false

Console.WriteLine(settings.HasFlag(CardSettings.SingleDeck));//true

Console.WriteLine(settings.HasFlag(CardSettings.Aniamation));//false


还可以检测多个标志位:

Console.WriteLine(settings.HasFlag(CardSettings.SingleDeck|CardSettings.FancyNumbers)); //False

Console.WriteLine(settings.HasFlag(CardSettings.SingleDeck | CardSettings.LargePictures)); //True


另一种判断方法是使用按位与运算,将该标志字与标志位相与,然后与位标志比较。

例如:检查是否设置了FancyNumbers 

CardSettings settings = CardSettings.SingleDeck | CardSettings.LargePictures;

bool useFancyNumber = (settings & CardSettings.FancyNumbers) == CardSettings.FancyNumbers;

Console.WriteLine(useFancyNumber);

输出: False


CardSettings settings = CardSettings.SingleDeck | CardSettings.FancyNumbers;

bool useFancyNumber = (settings & CardSettings.FancyNumbers) == CardSettings.FancyNumbers;

Console.WriteLine(useFancyNumber);

输出:True



Flags特性

Flags特性不会改变结算结构,却提供了一些方便的特性。

可以组成成位标志。ToString( )方法提供了更多的格式化信息,

CardSettings settings = CardSettings.SingleDeck | CardSettings.FancyNumbers;

Console.WriteLine(settings.ToString());

输出:

SingleDeck, FancyNumbers


settings = CardSettings.Aniamation; 

Console.WriteLine(settings.ToString());

输出:

Aniamation


3.关于枚举的更多内容

枚举只有单一的成员类型:声明的成员常量

不能对成员使用修饰符

由于成员是静态的,即使在没有枚举类的变量时也可以访问它们。

枚举类型.成员变  访问方式


其它一些枚举类型的静态方法:GetNames,GetName,GetValues

Console.WriteLine($"{Enum.GetName(typeof(TrafficLight),1)}"); //Green

Console.WriteLine($"{Enum.GetName(typeof(TrafficLight), 3)}"); //Yellow


foreach (var n in Enum.GetNames(typeof(TrafficLight)))

{

        Console.WriteLine(n);

  }

输出:

Green

Yellow

Red


foreach (var item in Enum.GetValues(typeof(TrafficLight)))

 {

           Console.WriteLine((int)item);

  }

输出:

1

3

5

你可能感兴趣的:(12 枚举--C#)