列挙体 基本定義と変換

基本文法

列挙体

列挙体は列挙子リストという定数の集合から成る
System.Enumを暗黙的に継承するちょっと特殊な値型
(このEnumに定義されるメソッド群を使えます)
定義した列挙体を継承することはできない


enum TrafficSignal 
{
    Blue,
    Yellow,
    Red
}

明示的な指定がない場合、各列挙子はint型であり、0から順に1づつ加算された値となる
(上例ではBlueが0でYellowが1でRedが2となる)



// byte,sbyte,short,ushort,int,uint,long,ulongを指定可能
// 列挙子に指定無い場合は前の値に1加算された値となる(C=21)
enum SampleEnum : long
{ 
    A=5, 
    B=20, 
    C 
}

フラグ

FlagsAttributeを付与することによりビットフィールドとして扱える


    [Flags]
    enum Device
    {
        None = 0,
        Monitor = 1,
        Keyborad = 1<<1,
        Mouse = 1<<2,
        All = Monitor | Monitor | Keyborad | Mouse
    }

// ビット演算可能
Device mine = Device.Monitor | Device.Keyborad;

// System.Enumに定義されたメソッドが使える
bool test1 = mine.HasFlag(Device.Monitor); // 戻値:true

bool test2 = mine.HasFlag(Device.Mouse);   // 戻値:false

string test = mine.ToString();             // 戻値:Monitor,Keyboard



列挙体と数値との変換


// 列挙体定義
enum TrafficSignal {Blue,Yellow,Red}

// 列挙値を数値に変換 キャストする
int value = (int)TrafficSignal.Red;  // 2

// 数値を列挙値に変換 キャストする
TrafficSignal ts = (TrafficSignal)2; // Red

// 数値を列挙値に変換 Enumのメソッドを使う
TrafficSignal ts = (TrafficSignal)Enum.ToObject(typeof(TrafficSignal), 2);

// なお、未定義の値が変換されないようチェックが必要
int value = 引数等;
TrafficSignal ts;
if(Enum.IsDefined(typeof(TrafficSignal),value ))
{
    ts = (TrafficSignal)Enum.ToObject(typeof(TrafficSignal), value );
}

列挙体と文字列との変換


// 列挙体定義
enum TrafficSignal {Blue,Yellow,Red}

// 列挙値を文字列に変換
string test = TrafficSignal.Red.ToString();

// 文字列を列挙値に変換
TrafficSignal ts = (TrafficSignal)Enum.Parse(typeof(TrafficSignal), "Red");

バージョニング問題

列挙体をあるライブラリで定義し、あるプロジェクトがそのライブラリをアセンブリ参照している場合において、参照している側の列挙値はコンパイル時に数値で扱われる。列挙体定義を変更した場合(明示的に数値を振ってない列挙子の順番を入れ替えるとか、追加や削除をするとか)において、参照しているプロジェクト側がリビルドしていない場合は、想定した列挙子ではない列挙子が使われる場合がありえます。