C#6.0語言規範(十四) 枚舉
一個枚舉類型是一個獨特的值類型(值類型)聲明一組命名的常量。
這個例子
1 enum Color 2 { 3 Red, 4 Green, 5 Blue 6 }
聲明了一個名為枚舉類型Color
與成員Red
,Green
和Blue
。
枚舉聲明
枚舉聲明聲明了一個新的枚舉類型。枚舉聲明以關鍵字開頭enum
,並定義枚舉的名稱,可訪問性,基礎類型和成員。
1 enum_declaration 2 : attributes? enum_modifier* ‘enum‘ identifier enum_base? enum_body ‘;‘? 3 ; 4 5 enum_base 6 : ‘:‘ integral_type 7 ; 8 9 enum_body 10 : ‘{‘ enum_member_declarations? ‘}‘ 11 | ‘{‘ enum_member_declarations ‘,‘ ‘}‘ 12 ;
每個枚舉類型都有一個相應的整數類型,稱為枚舉類型的基礎類型。此基礎類型必須能夠表示枚舉中定義的所有枚舉器值。enum聲明可以顯式地聲明基礎類型的byte
,sbyte
,short
,ushort
,int
,uint
,long
ulong
。請註意,char
不能用作基礎類型。未明確聲明基礎類型的枚舉聲明具有基礎類型int
。
這個例子
1 enum Color: long 2 { 3 Red, 4 Green, 5 Blue 6 }
聲明一個基礎類型為的枚舉long
。開發人員可能會選擇使用基礎類型(long
如示例中所示)來啟用範圍內long
但不在範圍內的值int
,或者為將來保留此選項。
枚舉修飾符
一個enum_declaration可任選地包括枚舉改性劑的一個序列:
1 enum_modifier 2 : ‘new‘ 3 | ‘public‘ 4 | ‘protected‘ 5 | ‘internal‘ 6 | ‘private‘ 7 ;
同一修飾符在枚舉聲明中多次出現是編譯時錯誤。
枚舉聲明的修飾符與類聲明(類修飾符)的含義相同。但請註意,枚舉聲明中不允許使用abstract
和sealed
修飾符。枚舉不能是抽象的,也不允許派生。
枚舉成員
枚舉類型聲明的主體定義零個或多個枚舉成員,它們是枚舉類型的命名常量。沒有兩個枚舉成員可以具有相同的名稱。
1 enum_member_declarations 2 : enum_member_declaration (‘,‘ enum_member_declaration)* 3 ; 4 5 enum_member_declaration 6 : attributes? identifier (‘=‘ constant_expression)? 7 ;
每個枚舉成員都有一個關聯的常量值。此值的類型是包含枚舉的基礎類型。每個枚舉成員的常量值必須在枚舉的基礎類型的範圍內。這個例子
1 enum Color: uint 2 { 3 Red = -1, 4 Green = -2, 5 Blue = -3 6 }
導致編譯時錯誤,因為在恒定的值-1
,-2
和-3
不在底層積分類型的範圍uint
。
多個枚舉成員可以共享相同的關聯值。這個例子
1 enum Color 2 { 3 Red, 4 Green, 5 Blue, 6 7 Max = Blue 8 }
顯示一個枚舉,其中兩個枚舉成員 - Blue
和Max
- 具有相同的關聯值。
枚舉成員的關聯值是隱式或顯式指定的。如果枚舉成員的聲明具有constant_expression初始值設定項,則該常量表達式的值(隱式轉換為枚舉的基礎類型)是枚舉成員的關聯值。如果枚舉成員的聲明沒有初始值設定項,則隱式設置其關聯值,如下所示:
- 如果枚舉成員是枚舉類型中聲明的第一個枚舉成員,則其關聯值為零。
- 否則,通過將文本上在前的枚舉成員的關聯值增加1來獲得枚舉成員的關聯值。此增加的值必須在可由基礎類型表示的值範圍內,否則會發生編譯時錯誤。
這個例子
1 using System; 2 3 enum Color 4 { 5 Red, 6 Green = 10, 7 Blue 8 } 9 10 class Test 11 { 12 static void Main() { 13 Console.WriteLine(StringFromColor(Color.Red)); 14 Console.WriteLine(StringFromColor(Color.Green)); 15 Console.WriteLine(StringFromColor(Color.Blue)); 16 } 17 18 static string StringFromColor(Color c) { 19 switch (c) { 20 case Color.Red: 21 return String.Format("Red = {0}", (int) c); 22 23 case Color.Green: 24 return String.Format("Green = {0}", (int) c); 25 26 case Color.Blue: 27 return String.Format("Blue = {0}", (int) c); 28 29 default: 30 return "Invalid color"; 31 } 32 } 33 }
打印出枚舉成員名稱及其相關值。輸出是:
1 Red = 0 2 Green = 10 3 Blue = 11
原因如下:
- 枚舉成員
Red
被自動賦值為零(因為它沒有初始值並且是第一個枚舉成員); - 枚舉成員
Green
被明確賦予值10
; - 並且枚舉成員
Blue
被自動分配的值大於文本上位於其前面的成員。
枚舉成員的關聯值不能直接或間接使用其自己的關聯枚舉成員的值。除了這種循環限制之外,枚舉成員初始化器可以自由地引用其他枚舉成員初始化器,而不管它們的文本位置如何。在枚舉成員初始值設定項中,其他枚舉成員的值始終被視為具有其基礎類型的類型,因此在引用其他枚舉成員時不需要強制轉換。
這個例子
1 enum Circular 2 { 3 A = B, 4 B 5 }
導致編譯時錯誤,因為聲明A
和B
是循環的。A
取決於B
明確,並B
取決於A
隱含。
枚舉成員的命名和範圍與類中的字段完全類似。枚舉成員的範圍是其包含枚舉類型的主體。在該範圍內,枚舉成員可以通過其簡單名稱來引用。在所有其他代碼中,枚舉成員的名稱必須使用其枚舉類型的名稱進行限定。枚舉成員沒有任何聲明的可訪問性 - 如果枚舉成員的包含枚舉類型可訪問,則可以訪問該成員。
System.Enum類型
類型System.Enum
是所有枚舉類型的抽象基類(這與枚舉類型的基礎類型不同且不同),並且繼承自的成員System.Enum
在任何枚舉類型中都可用。裝箱轉換(裝箱轉換)從任何枚舉類型來存在System.Enum
,和取消裝箱轉換(解包轉換)從存在System.Enum
於任何枚舉類型。
請註意,System.Enum
它本身不是enum_type。相反,它是一個class_type,從中派生所有enum_type。該類型System.Enum
繼承自類型System.ValueType
(System.ValueType類型),而類型繼承自類型object
。在運行時,type的值System.Enum
可以是null
或對任何枚舉類型的盒裝值的引用。
枚舉值和操作
每個枚舉類型定義一個不同的類型; 在枚舉類型和整數類型之間或兩個枚舉類型之間進行轉換需要顯式枚舉轉換(顯式枚舉轉換)。枚舉類型可以采用的值集不受其枚舉成員的限制。特別是,枚舉的基礎類型的任何值都可以強制轉換為枚舉類型,並且是該枚舉類型的唯一有效值。
枚舉成員具有包含枚舉類型的類型(在其他枚舉成員初始值設定項中除外:請參閱枚舉成員)。枚舉成員的值枚舉類型中聲明E
相關聯的值v
是(E)v
。
以下運算符可以在枚舉類型的值可以使用:==
,!=
,<
,>
,<=
,>=
(枚舉比較運算符),二進制+
(加法運算符),二進制-
(減法運算符), ,^
,(&
枚舉邏輯運算符), (按位求補運算符),並(後綴增量和減量運算符以及前綴增量和減量運算符)。|
~
++
--
每個枚舉類型都自動派生自類System.Enum
(反過來,派生自System.ValueType
和object
)。因此,此類的繼承方法和屬性可用於枚舉類型的值。
C#6.0語言規範(十四) 枚舉