連載

C#入門

第16回 列挙型の活用

(株)ピーデー
川俣 晶
2001/11/23


数値指定時のトラブル例

 以下は、数値指定時に起こるトラブルの一例である。内容としては、ただ単に列挙型の値をコンソールに出力しているだけで何も問題がないように見える。

 1: using System;
 2:
 3: namespace ConsoleApplication9
 4: {
 5:   enum Sample
 6:   {
 7:     A,
 8:     B,
 9:     C = 10,
10:     D,
11:     E = B
12:   }
13:   class Class1
14:   {
15:     static void Main(string[] args)
16:     {
17:       Console.WriteLine( Sample.A );
18:       Console.WriteLine( Sample.B );
19:       Console.WriteLine( Sample.C );
20:       Console.WriteLine( Sample.D );
21:       Console.WriteLine( Sample.E );
22:     }
23:   }
24: }
数値指定時のトラブル例を示したサンプル・プログラム9
単に列挙型の値をコンソールに出力しているだけだが……。

 これを実行すると以下のようになる。

サンプル・プログラム9の実行結果
“B”が出力されると予想される場所に“E”が表示されている。

 見て分かるとおり、本来A〜Eが順に出力されるはずが、Bの表示がEに化けている。その原因は、11行目の“E = B”にある。列挙型が内部的に数値で処理されるため、同じ数値に割り当てられた名前は区別することができない。つまり、Sample.Bを使ったのか、Sample.Eを使ったのかは、列挙型の値からは区別できない。そこで、Sample.Bを指定しているのに、同じ値を持つEがコンソールに表示されてしまうという現象が起きるのである。これを回避するには、同じ値を別の名前に割り当てなければよい。数値を明示的に指定しなければ、自動的に同じ値の割り当ては回避されるので、初心者は数値指定を避けた方がトラブルに巻き込まれる危険が減る。

列挙型の数値計算

 列挙型は数値ではないが、内部的に数値として処理される。そのため、すべてではないが、限定的な数値計算が実行できるようになっている。以下は列挙型を数値計算に用いたサンプル・ソースである。

 1: using System;
 2:
 3: namespace ConsoleApplication10
 4: {
 5:   enum Sample
 6:   {
 7:     A,
 8:     B,
 9:     C
10:   }
11:   class Class1
12:   {
13:     static void Main(string[] args)
14:     {
15:       Sample a = Sample.A;
16:       Sample r = a + 1;
17:       Sample b = Sample.B;
18:       //Sample s = a + b; //演算子 '+' を 'ConsoleApplication10.Sample' と 'ConsoleApplication10.Sample' 型のオペランドに適用することはできません。
19:       Console.WriteLine( r );
20:     }
21:   }
22: }
列挙型を数値計算に用いたサンプル・プログラム10
列挙型の値同士の足し算はコンパイル・エラーとなる。

 これを実行すると以下のようになる。

サンプル・プログラム10の実行結果
“A”に1を足したため、次の要素を示す“B”が表示されている。

 16行目は、Aが代入されている変数aに1を足すコードが記述されている。このコードは正常に実行でき、結果はBとなる。これは、5〜10行目の列挙型の定義で、Aの次がBであることによる結果である。一方、18行目のように、列挙型の値と列挙型の値を足し算するような計算はエラー扱いとなり、コンパイルできない。Aに1を足すと次の要素を示す、という計算に意味はあっても、AとBを足す、という計算に意味はないからだ。

値の名前を得る

 C#の列挙型は、すべてSystem.Enumクラスを継承したものとして自動的に定義される。そのため、System.Enumクラスを処理するためのさまざまなメソッドがすべて利用できる。例えば、列挙型のある値に対応する名前を得るには、以下のように記述することができる。

 1: using System;
 2:
 3: namespace ConsoleApplication11
 4: {
 5:   enum Era
 6:   {
 7:     Meiji,
 8:     Taisho,
 9:     Showa,
10:     Heisei
11:   }
12:   class Class1
13:   {
14:     static void Main(string[] args)
15:     {
16:       Era t = Era.Taisho;
17:       string name = Era.GetName( Type.GetType("ConsoleApplication11.Era"), t );
18:       Console.WriteLine( name );
19:     }
20:   }
21: }
列挙型の値に対応する名前を得るサンプル・プログラム11
System.EnumクラスにあるGetNameメソッドを使用している。

 これを実行すると以下のようになる。

サンプル・プログラム11の実行結果
GetNameメソッドに列挙型の値を渡すと、それに対応している名前が文字列で返される。

 ポイントは17行目である。GetNameメソッドは、System.Enumクラスのstaticなメソッドである。第1引数に列挙型の型を、第2引数に判定したい値を渡すと、列挙型の名前を返してくれる。つまり、Era.Taishoという値をGetNameメソッドの第2引数に渡すと、対応する文字列“Taisho”が返される。

列挙型のすべての名前を得る

 System.Enumクラスには列挙型のすべての名前を得るメソッドもある。以下はそれを用いた例である。

 1: using System;
 2:
 3: namespace ConsoleApplication12
 4: {
 5:   enum Era
 6:   {
 7:     Meiji,
 8:     Taisho,
 9:     Showa,
10:     Heisei
11:   }
12:   class Class1
13:   {
14:     static void Main(string[] args)
15:     {
16:       string [] names = Era.GetNames( Type.GetType("ConsoleApplication12.Era") );
17:       foreach( string s in names )
18:       {
19:         Console.WriteLine( s );
20:       }
21:     }
22:   }
23: }
列挙型のすべての名前を得るサンプル・プログラム12
System.EnumクラスにあるGetNamesメソッドを使用している。

 これを実行すると以下のようになる。

サンプル・プログラム12の実行結果
列挙型であるEra型に含まれるすべての要素の名前が列挙される。

 16行目のGetNamesメソッドは、引数として与えられた列挙型に含まれるすべての名前を、文字列の配列として返す。これを調べれば、列挙型に含まれるすべての名前を容易にプログラム中で知ることができる。


 INDEX
  第16回 列挙型の活用
    1.列挙型とは何か
    2.数値として使う列挙型
  3.数値指定時のトラブル例
    4.列挙型のすべての数値を得る
 
「C#入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間