1.枚舉
枚舉是由程序員定義的類型挺狰,與結(jié)構(gòu)一樣身隐。
枚舉是值類型廷区,直接存儲(chǔ)它們的數(shù)據(jù),不是分開存儲(chǔ)成引用和數(shù)據(jù)贾铝。
枚舉只是一種類型的成員:命名的整數(shù)值常量隙轻。成員聲明之間逗號(hào)分隔。
例如:
enum TrafficLight
{
? ? ? ? Green,
? ? ? ? Yellow,
? ? ? ? Red
? ?}
使用關(guān)鍵字enum聲明垢揩,后加枚舉名稱 TrafficLight,枚舉值之間逗號(hào)分隔大脉,枚舉值使用大括號(hào)包裹。
每個(gè)枚舉值默認(rèn)為int.編譯器對(duì)第一個(gè)成員賦值為0水孩,后續(xù)每個(gè)成員賦值都比前一個(gè)多1.
測(cè)試:
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
設(shè)置底層類型和顯示值
類型可以是任何整數(shù)類型琐驴。盡管不能有重復(fù)名稱俘种,但是可以有重復(fù)值秤标。
//等效
? ? enum TrafficLight:int
? ? {
? ? ? ? Green =0,
? ? ? ? Yellow =1,
? ? ? ? Red=2
? ? }
也可以自定義值:
enum TrafficLight:int
? ? {
? ? ? ? Green =1,
? ? ? ? Yellow =3,
? ? ? ? Red=5
? ? }
給隱式成員編號(hào)
可顯式給任何成員變量賦值,如果不初始化成員常量宙刘,編譯器隱式給它賦初值苍姜。
enum Level
? ? {
? ? ? ? One =10,
? ? ? ? Two,
? ? ? ? Three=15,
? ? ? ? Four,
? ? ? ? Five=1
? ? }
測(cè)試:
Console.WriteLine($"{(int)Level.One} {(int)Level.Two} {(int)Level.Three} {(int)Level.Four} {(int)Level.Five}");
輸出:10 11 15 16 1
從輸出可以看出,可任意給枚舉成員變量指定整型值悬包,其后的變量值自動(dòng)加1衙猪,指定的值是可以跳變的,也可以默認(rèn)布近。
2.位標(biāo)志
單個(gè)字Single word的不同位表示一組開關(guān)標(biāo)志的緊湊方法垫释。成為標(biāo)志字 flag word.
一般步驟:
(1) 確定需要多少個(gè)標(biāo)志位,選擇一種有足夠多的位的無符號(hào)類型來保存它撑瞧。
(2) 確定每個(gè)位位置代表什么棵譬,并給它們一個(gè)名稱。
(3) 使用按位或OR 運(yùn)算符在持有該標(biāo)志位的字中設(shè)置適當(dāng)?shù)奈?/p>
(4) 使用按位與 AND運(yùn)算符或HasFlag方法檢查是否設(shè)置了特定位標(biāo)志
從C# 7.0開始预伺,可以使用二進(jìn)制表示法
使用Flags特性可帶來一些便利订咸。
[Flags]
? ? enum CardSettings:uint
? ? {
? ? ? ? SingleDeck? ? = 0x01,
? ? ? ? LargePictures = 0x02,
? ? ? ? FancyNumbers? = 0x04,
? ? ? ? Aniamation? ? = 0x08
? ? }
測(cè)試代碼:
CardSettings settings = CardSettings.SingleDeck | CardSettings.LargePictures;
?Console.WriteLine($"{settings} {(uint)settings}"); //輸出:3
使用Flags 屬性的標(biāo)志枚舉變量可以使用邏輯位運(yùn)算。
如果指定的標(biāo)志位有值返回true,否則返回false
Console.WriteLine(settings.HasFlag(CardSettings.SingleDeck));//true
Console.WriteLine(settings.HasFlag(CardSettings.Aniamation));//false
還可以檢測(cè)多個(gè)標(biāo)志位:
Console.WriteLine(settings.HasFlag(CardSettings.SingleDeck|CardSettings.FancyNumbers)); //False
Console.WriteLine(settings.HasFlag(CardSettings.SingleDeck | CardSettings.LargePictures)); //True
另一種判斷方法是使用按位與運(yùn)算酬诀,將該標(biāo)志字與標(biāo)志位相與脏嚷,然后與位標(biāo)志比較。
例如:檢查是否設(shè)置了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特性不會(huì)改變結(jié)算結(jié)構(gòu)瞒御,卻提供了一些方便的特性父叙。
可以組成成位標(biāo)志。ToString( )方法提供了更多的格式化信息葵腹,
CardSettings settings = CardSettings.SingleDeck | CardSettings.FancyNumbers;
Console.WriteLine(settings.ToString());
輸出:
SingleDeck, FancyNumbers
settings = CardSettings.Aniamation;?
Console.WriteLine(settings.ToString());
輸出:
Aniamation
3.關(guān)于枚舉的更多內(nèi)容
枚舉只有單一的成員類型:聲明的成員常量
不能對(duì)成員使用修飾符
由于成員是靜態(tài)的高每,即使在沒有枚舉類的變量時(shí)也可以訪問它們。
枚舉類型.成員變? 訪問方式
其它一些枚舉類型的靜態(tài)方法: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