程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .NET中的枚舉(Enum)

.NET中的枚舉(Enum)

編輯:關於.NET

摘要:.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個值以及它們任意組合(或運算)剛好能夠代表種情況(其中是單個枚舉,其他都是組合),對標志枚舉使用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();
            
}

測試結果如下:

2016_10_96af7a07-7fcf-46f5-a728-f3f92c4effa1

總結一些設計枚舉的規范

  • 簡單枚舉的命名采用單數形式。
  • 不要使用Enum、Flag、Flags作為枚舉類型的後綴。
  • 不要給枚舉值的命名加上枚舉類型名前綴,比如FontStyleBlod這樣是不規范的。
  • 使用枚舉代替一些固定的常量集合。
  • 使用枚舉作為參數、屬性、返回值,來保證該API是強類型的API。
  • 考慮給枚舉提供一個None=0的枚舉值。
  • 給標志枚舉賦值為2的指數值。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved