一連の名前に値を関連付ける列挙型。C++などにもあったものだが、C#ではやや機能が異なる。サンプル・プログラムとともにその挙動を確認していく。
本記事は、(株)技術評論社が発行する書籍『新プログラミング環境 C#がわかる+使える』から許可を得て転載したものです。同書籍に関する詳しい情報については、本記事の最後に掲載しています。
列挙型は、一連の名前に値を関連付ける機能を実現する。しかし、C#の列挙型はC++などに存在する列挙型とは機能がやや異なる。本章では、列挙型の使い方とともに、C++などのプログラミング言語の列挙型との相違も解説しよう。
プログラムを作成していると、文字列だが出現する可能性のある語句/つづりが限定されている、というデータに出会うことがある。例えば、日本の年号は明治、大正、昭和、平成と続いているが、これは文字列とは性格が異なっている。文字列なら太郎や花子を代入してもよいが、それらは年号ではない。かといって、明治、大正、昭和、平成を0から3までの整数に割り当ててコーディングしたら、意味不明になってしまう。ある年が対象かどうかを判定するために、1かどうか判定する式を書くことになるが、この1が大正であることは容易には読み取れない。そこで、数値に名前を割り当ててコーディングしたりするわけだが、C#では、このような目的に適する列挙型(enum)というデータ型を持っている。本章ではそれを解説する。
まず、列挙型を用いた最も基本的な例をList 16-1に示す。
1: using System;
2:
3: namespace Sample001
4: {
5: enum Era
6: {
7: Meiji,
8: Taisho,
9: Showa,
10: Heisei
11: }
12: class Class1
13: {
14: static void WriteEra( Era t )
15: {
16: switch( t )
17: {
18: case Era.Meiji:
19: Console.WriteLine("明治");
20: break;
21: case Era.Taisho:
22: Console.WriteLine("大正");
23: break;
24: case Era.Showa:
25: Console.WriteLine("昭和");
26: break;
27: case Era.Heisei:
28: Console.WriteLine("平成");
29: break;
30: }
31: }
32: [STAThread]
33: static void Main(string[] args)
34: {
35: Era t = Era.Taisho;
36: WriteEra( t );
37: }
38: }
39: }
これを実行するとFig.16-1のようになる。
まず、5〜11行目が、列挙型を定義している。ここでは、Eraという名前で、Meiji、Taisho、Showa、Heiseiという4つの名前を含む列挙型を定義している。Eraはデータ型なので、35行目のようにEra型の変数などを宣言できる。Era型の変数には、上記の4種類の名前しか代入できない。名前は単独で記述することはできない。つまり、「Era t = Taisho;」と書くことはできない。名前がEra型であることを明示するために、名前の手前に「Era.」を付加して、「Era t = Era.Taisho;」と記述しなければならない。
宣言された列挙型は、文字列というよりも数値のように振る舞うと考えておけば間違いない。実際、後で述べるように中身は数値として処理される。しかし、ほとんどの場合、列挙型は数値とは異なる意味を与えられているので、16〜30行目のswitch文に見られるように、1個ずつの要素を独立して判断して、処理を決めるのが基本になる。上級者になれば、列挙型を数値扱いするトリックを使うことで、効率アップしたり、プログラムを短くしたりすることもできるが、初心者にはトラブルのもとなので、お勧めしない。
一番手軽に値を出力できるConsole.WriteLineメソッドは、すでにお世話になっているC#プログラマーも多いと思う。このメソッドに直接列挙型の値を渡したら、何が起こるだろうか? 実際にやってみたものが、List 16-2のサンプル・ソースである。
1: using System;
2:
3: namespace Sample002
4: {
5: enum Era
6: {
7: Meiji,
8: Taisho,
9: Showa,
10: Heisei
11: }
12: class Class1
13: {
14: [STAThread]
15: static void Main(string[] args)
16: {
17: Era t = Era.Taisho;
18: Console.WriteLine( t );
19: }
20: }
21: }
これを実行するとFig.16-2のようになる。
Fig.16-2を見て分かるとおり、列挙型をConsole.WriteLineメソッドに直接渡すと、その名前そのものが出力される。C++プログラマーは、この点で挙動が異なることに注意していただきたい。C++では、このような場合、名前ではなく数値が出力されてしまうのである。C++の列挙型は数値の別名にすぎないが、C#の列挙型はもう少し多くの管理情報を実行時に持っている。機能的にイコールではない。
C#はキーワードに漢字を使用できる。では、年号を漢字で書いたら何が起こるだろうか? List 16-3がその例である。
1: using System;
2:
3: namespace Sample003
4: {
5: enum Era
6: {
7: 明治,
8: 大正,
9: 昭和,
10: 平成
11: }
12: class Class1
13: {
14: [STAThread]
15: static void Main(string[] args)
16: {
17: Era t = Era.大正;
18: Console.WriteLine( t );
19: }
20: }
21: }
これを実行するとFig.16-3のようになる。
見てのとおり、漢字で書かれたキーワードがそのままコンソールに出てきている。この程度のシンプルなデータなら、最初のサンプル・ソースのようにいちいちswitch文で切り分けるのではなく、最初から目的の名前を列挙型定義で書いてしまっても問題ないだろう。ただし、名前に使用できる文字には制限がある(例えば空白文字や区切りのカンマなどは書けない)ので、いつでも可能というわけではない。
Copyright© Digital Advantage Corp. All Rights Reserved.