[C#] Enum 與 [Flags] 屬性

  • 27880
  • 0
  • 2010-01-23

[C#] enum 與 [Flags] 屬性

Introduction

enum 關鍵字用來宣告列舉型別 (Enumeration),是由一組稱為列舉值清單的具名常數所構成的獨特型別。

通常最好是在命名空間內直接定義 enum,讓該命名空間中的所有類別都能同樣便利地存取它。不過,enum 也可以透過巢狀方式置於個類別或結構 (Struct) 中。

enum 的核准型別為 byte、sbyteshortushortintuintlongulong

列舉最常用在的地方,就是搭配 swith case 來完成 if else 的功能;

另外,搭配 [Flags] 屬性,System.FlagsAttribute ,並定義值來建立位元旗標列舉,這樣就可以對其執行 AND、OR、NOT 和 XOR 位元運算。

例如:我們可能判斷某一個使用者,他擁有哪些使用權限;或是,某個區域的落點是屬於哪個群組。

 

Example


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestFlag {

    [Flags]
    public enum EActions {
        //這邊我使用 2 的冪次,整數表示,
        //也可使用 16 進制表示,如:0x01、0x08...         
        None = 0,
        Stop = 1,
        Sleep = 2,
        Eat = 4,
        Run = 8,
        All = None | Stop | Sleep | Eat | Run
    };

    class Program {
        static void Main(string[] args) {

            EActions eAct1 = EActions.All;

            //設定旗標
            EActions eAct2 = EActions.Eat | EActions.Run;

            Console.WriteLine("(int)eAct1 : " + (int)eAct1);
            Console.WriteLine("eAct1 : " + eAct1);
            Console.WriteLine("(int)eAct2 : " + (int)eAct2);
            Console.WriteLine("eAct2 : " + eAct2);
            
            //取得列舉名稱
            string s = Enum.GetName(typeof(EActions),8);
            Console.WriteLine("s : " + s);

            //將字串轉換為一個對等的列舉型別物件。
            string sAct = "Run";
            EActions eAct3 = (EActions)Enum.Parse(typeof(EActions),sAct);
            Console.WriteLine("eAct3 : " + eAct3);

            Console.ReadLine();
        }
    }
}

結果:

tmp

 

若去掉 [Flags] 屬性:

tmp

 

 

注意事項:

  • 若要對列舉設定旗標,請使用邏輯 OR 運算子,如下列範例所示:

// Initialize with two flags using bitwise OR.
meetingDays = Days2.Tuesday | Days2.Thursday;

// Set an additional flag using bitwise OR.
meetingDays = meetingDays | Days2.Friday;

Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Tuesday, Thursday, Friday

// Remove a flag using bitwise XOR.
meetingDays = meetingDays ^ Days2.Tuesday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Thursday, Friday

 

  • 若要判斷是否有設定特定旗標,請使用邏輯 AND 運算,如下列範例所示:

// Test value of flags using bitwise AND.
bool test = (meetingDays & Days2.Thursday) == Days2.Thursday;
Console.WriteLine("Thursday {0} a meeting day.", test == true ? "is" : "is not");
// Output: Thursday is a meeting day.
  • 確保0為值類型的有效狀態

請參考:[C#]Effective C# 條款八: 確保0為值類型的有效狀態 - Level Up- 點部落

 

Link:

http://msdn.microsoft.com/zh-tw/library/sbbt4032%28VS.80%29.aspx

http://msdn.microsoft.com/zh-tw/library/sbbt4032.aspx

http://msdn.microsoft.com/zh-tw/library/cc138362.aspx

http://msdn.microsoft.com/zh-tw/library/system.flagsattribute.aspx

 

File:TestFlag.rar

 

<<後記>>

今天看了 Dotjum 瓶水相逢.Net 兩位前輩的文章,又感動到了,

文章之詳細,真是慚愧,小弟寫的不怎樣還真的在這邊發文章,

唉! 貼出連結也來讓大家感動一下(甚麼! 既然你們已經看過了,看來我又慢了)

http://www.dotblogs.com.tw/dotjum/archive/2008/06/22/4356.aspx

http://www.dotblogs.com.tw/chhuang/archive/2008/04/26/3514.aspx

FlagsAttribute Class

三小俠  小弟獻醜,歡迎指教