.NET中的枚举(Enum)
摘要:.NET中的枚舉分為簡單枚舉和標志枚舉,這次主要總結一下標志枚舉適用條件,以及它的使用方法,并在文章的最后列舉枚舉使用的一些規范。
在剛接觸.NET的枚舉時,只用簡單的枚舉,對于標記枚舉,只知道是在枚舉類型加上Flags特性,然后給枚舉值賦予十六進制的值,并且書中還特別明確規定值必須是以2的指數才可以,這樣可以方便在使用時,對多個枚舉值進行或運算。隨著對.NET的了解不斷的深入,現在終于明白了標志枚舉的適用場合以及它的使用方法,因此在這里總結一下。
標志枚舉的適用條件
在System.Drawing命令空間中有一個FontStyle標志枚舉,專門用來設置字體的風格,有Blod、Italic、Regular、Strikeout、Underline這5種風格。當然我們需要設置字體為單個一種風格時,那么FontStyle枚舉的用法和簡單枚舉沒什么區別,比如,我們需要把字體風格為設置為粗體,代碼如下:
System.Drawing.Font font = new System.Drawing.Font("宋體",12,FontStyle.Bold);但是,如果我們需要設置字體的風格為粗體的同時還要需要斜體和下劃線呢?對于這種情況,簡單枚舉就不適用了,這就必須使用標志枚舉的進行組合才能辦到了,代碼如下:
System.Drawing.Font font = new System.Drawing.Font("宋體",12, FontStyle.Bold|FontStyle.Italic|FontStyle.Underline);通過這樣的組合就能夠達到我們想要的效果。
自定義FontStyle標志枚舉,一探究竟
下面我們自己設計一個FontStyle,看看它的內部是如何實現的。代碼如下:
[Flags] public enum FontStyle: byte { Bold=0x01,Italic = 0x02,Regular = 0x04,Strikeout=0x08,Underline=0x10, }上面的定義了一個FontStyle枚舉,該枚舉繼承byte類型,通過加上Flags特性,使它成為標志枚舉,并且為每一個枚舉值賦值一個十六進制的值,每一個值都是2的指數值。下面將詳細解釋一些為什么要使用2的指數來進行賦值。
為什么使用2的指數值對枚舉進行賦值
首先我們要明白,二進制的或運算,或運行無非就4種情況,
0|0=0; 0|1=1; 1|0=1; 1|1=1;那么二進制10101010和01010101進行或運算就等于11111111,明白了二進制的或運算,再仔細想想,一個字節8位二進制,可以代表0-255。其中1,2,4,8,16,32,64,128是2的指數,分別代表的二進制的00000001,00000010,00000100,00001000,00010000,00100000,01000000,10000000,它們的每個取值剛好是將8位中的某一位設為1。那么這8個值以及它們任意組合(或運算)剛好能夠代表$C^1_8+C^2_8+C^3_8+C^4_8+C^5_8+C^6_8+C^7_8+C^8_8=255 $種情況(其中$C_8^1?$是單個枚舉,其他都是組合),對標志枚舉使用2的指數值進行賦值,能夠進行任意的組合,并且任意組合后的值不會有重復。這就是為什么要使用2的指數值對標志枚舉進行復制的原因。順便這里再多說一句,賦值的時候為什么不用10進制,而是用16進制的表示法,前面我們分析了,標志枚舉的組合最后都將進行二進制的或運算,而我們在賦值的時候用16進制會更加表現明顯,因為每一個16進制的數值,剛好代表二進制4個位,所以兩個16進制的數就能代表一個字節,比如0x11,我們化為二進制,只需要對兩個1分別換算4個二進制位就行了,1=0001,所以0x11就代表00010001,如果用十進制17來表示,就沒那么輕易地看出它的二進制表示。
如何處理組合枚舉
當我們把標志枚舉賦值為2的指數值之后,我們就可以組合的使用這些枚舉值,以期達到我們想要的效果,那么在函數設計中,我們是如何來處理傳入進來的枚舉組合值呢?其實也非常簡單,正是因為他們任意的組合都不會重復,因此每一個數值可以代表其中的一個枚舉值或者是一個組合,比如,FontStyle.Bold|FontStyle.Italic|FontStyle.Underline這個組合所代表的數值就位0x01|0x02|0x10=19.
下面設計一個函數處理傳入進來的枚舉值。代碼如下:
static void Test(FontStyle fontStyle) {switch ((byte)fontStyle){ case 1:Console.WriteLine("Bold");break;case 2:Console.WriteLine("Italic");break;case 3:Console.WriteLine("Bold&Italic");break;case 4:Console.WriteLine("Regular");break;case 6:Console.WriteLine("Regular&Italic");break;case 8:Console.WriteLine("Strikeout");break;case 9:Console.WriteLine("Strikeout&Bold");break;case 10:Console.WriteLine("Strikeout&Italic");break;case 11:Console.WriteLine("Strikeout&Italic&Bold");break;case 16:Console.WriteLine("Underline");break;case 19:Console.WriteLine("Bold&Italic&Underline");break;//else} }因為枚舉在CLR內部實現可以看做是數值類型。在Test函數內部我們需要用Switch去判斷傳入的枚舉值,確定是否單個枚舉還是組合后的值,并對其做出相應的處理。下面給出測試代碼。
static void Main(string[] args) {Test(FontStyle.Bold);Test(FontStyle.Strikeout|FontStyle.Italic);Test(FontStyle.Bold|FontStyle.Italic|FontStyle.Underline);Console.ReadKey();}測試結果如下:
總結一些設計枚舉的規范
- 簡單枚舉的命名采用單數形式。
- 不要使用Enum、Flag、Flags作為枚舉類型的后綴。
- 不要給枚舉值的命名加上枚舉類型名前綴,比如FontStyleBlod這樣是不規范的。
- 使用枚舉代替一些固定的常量集合。
- 使用枚舉作為參數、屬性、返回值,來保證該API是強類型的API。
- 考慮給枚舉提供一個None=0的枚舉值。
- 給標志枚舉賦值為2的指數值。
轉載于:https://www.cnblogs.com/mingjiatang/p/5947335.html
總結
以上是生活随笔為你收集整理的.NET中的枚举(Enum)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql中如何把字符串转换成日期类型
- 下一篇: fiddler和xampp安装成功后,网