3-7 列挙型 (Enum)
3-7-1 列挙型とは?
列挙型は、ある特定の値しか代入できないデータ型で、プログラマが任意につくることができるカスタムデータ型です。以下の例では、FlyType という列挙型が定義されています(1 行目 ~ 5 行目)。この FlyType は、ほかの通常のデータ型と同じように扱うことができ、変数定義の際のデータ型としても使えます(WinApp2 プロジェクトの Form1 クラスブロック内に記述することを想定)。
[例] FlyType という型名の列挙型を定義
1: Enum FlyType As Long
2: Economy
3: Business
4: First
5: End Enum
6:
7: Private Sub Button1_Click(ByVal sender As System.Object, ...
8: Dim T As FlyType
9: T = FlyType.Business '3 つのうちのどれか
10: End Sub
1 行目から 5 行目では、Enum~End Enum というブロックがあり、FlyType という名前の列挙型が定義されています。この列挙型は、3 つのどれか(2 行目 ~ 4 行目)の値を代入できることを意味しています。「Ecomony」、「Business」、「First」 という言葉を、そのままデータとして扱うことができます。8 行目は、FlyType 型の変数 T の定義です。Dim ステートメントの後ろに 「As FlyType」 と記述してあることから、Integer 型や String 型と同じように、データ型として扱われていることがわかるでしょう。9 行目では、列挙された値の 3 つのうち、1 つを変数 T に代入しています。
なお、列挙された値は文字列ではなく、内部的には整数として扱われます。1 行目の記述に As Long がついており、列挙型の値が、内部的には Long 型の整数が、列挙された値に自動的に割り当てられています。つまり、前記の 「Economy」 や 「Business」 は、特定の整数に対する別名とみなすことができます。列挙型で列挙している値 「Ecomony」 は、ダブルコーテーションで囲んでいないことに注意してください。
このように、数値にわかりやすい名前をつけておけば、以下のようなメソッドでは、何を引数で渡すのかがわかりやすくなります。また、Option Strict をオンにすると、列挙型の変数は、列挙された限られた範囲の値しか代入できなくなるので、誤使用する可能性も減ります(Option Strict については、3-1-5 「Dim 文によるさまざまな変数の宣言」を参照)。
[例] 列挙型を引数にする(引数 T は、3 つの値のうちの 1 つ)
1: Private Sub RegPoint(ByVal T As FlyType, ByVal Point As Long)
2: '飛行機の搭乗ポイント加算処理
3: End Sub
なお、ここでは、WinApp2 プロジェクトの Form1 クラス内に列挙型 FlyType を定義しました。しかし、本来、列挙型は型の 1 つであり、Form1 クラスもフォームを表す型の 1 つです。つまり、Class~End Class のブロックや Enum~End Enum のブロックはどちらも型を表すもので、同列に扱うことができます。そのため、Enum ブロックは、Class ブロックの外に書くことができます。
ただし、メソッド内に記述することはできません。
3-7-2 列挙型の定義と使用
列挙型を定義するには、以下のように Enum キーワードを使って型名を宣言し、値を列挙します。
修飾句 Enum 列挙型名 As データ型
値 1
値 2
値 3
...
End Enum
修飾句の意味については、第 5 章 「クラスの定義と実装」 で説明します。それまでは、Public をつけておくことにします。また、値については、ある特定の整数値を明示的に割り当てることもできます。ただし、そのプログラムで、特定の数値を割り振ることに意味がなければ、単に値の名前だけ列挙すれば十分です。
[例] 列挙の値に数値を割り振る
1: Public Enum FlyType As Long
2: First = 150
3: Business = 125
4: Economy = 100
5: End Enum
なお、列挙型では、列挙された名前に割り与えられる値は整数に限られます。つまり、1 行目の As 句に記述できるデータ型は、Byte、Short、Integer、Long のうちのいずれかです。
また、先に触れたように、この列挙型の定義する場所は、クラスブロックの中でもクラスの外でも可能です。クラスも型であり、列挙型も型であるので、同列に定義することができます。ただし、メソッド内に定義することはできません。
いったん、前記のように列挙型を定義すると、その型は変数定義の際の変数の型として利用することができます。以下に列挙型の例を示します(WinApp2 プロジェクトの Form1.vb に記述することを前提にしています。一部省略しています)。
[例] 列挙型の定義
1: Public Class Form1
2: Inherits System.Windows.Forms.Form
3:
4: Public Enum FlyType As Long
5: Economy
6: Business
7: First
8: End Enum
9:
10: Private Sub Button1_Click(ByVal sender As System.Object, ...
11: Dim T As FlyType 'FlyType 型
12: Dim R As OurRank 'OurRank 型
13: T = FlyType.Economy
14: R = OurRank.Normal
15: End Sub
16:
17: End Class
18:
19: Public Enum OurRank As Integer
20: High
21: Normal
22: Low
23: End Enum
この例では、2 つの列挙型、FlyType と OurRank が定義されています。FlyType は Form1 クラスのブロック内に、OurRank は Form1 クラスのブロック外に定義されています。
これら列挙型の変数を定義しているのが、11 行目と 12 行目です。どちらも、As 句の後ろに列挙型の名前がきています。
列挙型の値を利用しているのが、13 行目と 14 行目です。列挙型の値を参照するときは 「FlyType.Economy」 のように、「列挙型名.値」 というようにどの列挙名の値であるかがわかるよう、ドットをつけて値を特定します。
なお、FlyType は Form1 というクラスブロック内にあるので、もっと正確にドットをつけて特定する場合、11 行目と 13 行目は以下のようになります。
[例] Form1 クラス内にある値型の特定
11: Dim T As Form1.FlyType
13: T = Form1.FlyType.Economy
ただし、11 行目や 13 行目のコードは、FlyType の定義と同じ Form1 クラスの中にあるので、「Form1.」 は省略することができます。
.NET Framework クラスライブラリではこのような列挙型が、あらかじめ多数定義されています。.NET Framework クラスライブラリを使用するためには、この列挙型の使用方法に慣れておく必要があります。