Select Caseステートメントの構文と例

Select Caseステートメントは、ある値を分類し、その分類に応じて実行する処理を分岐させるための構文です。 構文の形式は次の通りです。 [ ]でくくった部分は省略することが可能な箇所です。

Select Caseステートメントの構文
Select [ Case ] 分類する値を保持する変数

   [ Case 値 [, 値 [, 値 ... ] ]
      [ ステートメント ] ]

   [ Case Else
      [ ステートメント ] ]

End Select

Select Caseステートメントを使った具体例を挙げると次のようになります。

Dim i As Integer = 3

' 変数iの値によって処理を分岐する
Select Case i

  Case 1
    ' iが1の場合
    Console.WriteLine("i は 1です")

  Case 2, 3
    ' iが2または3の場合
    Console.WriteLine("i は 2 または 3 です")

  Case 4
    ' iが4の場合
    Console.WriteLine("i は 4 です")

  Case Else
    ' それ以外の場合
    Console.WriteLine("i はそれ以外の値です")

End Select

Select Caseステートメント内で記述されるCase のうち、いずれかに一致するものがあればそのCase以下のステートメントが実行されます。 Caseで分類する値はカンマ,で区切ることにより複数記述することができます。 この場合、どれか1つでも一致する値があれば、そのCase以下のステートメントが実行されます。 Case Elseの部分は、値がどの分類にも当てはまらなかった場合に実行されます。

フォールスルー

Select Caseステートメントでは、どこか一箇所でも一致する分類があった場合は、それ以降は他の分類と一致するかどうかの評価はされません。 つまり、VB.NETのCaseでは、Cなどのcaseラベルとは異なりフォールスルーしません。 複数のCaseで同じ値を記述することはできますが、実行されるステートメントは最初に一致する値が見つかった箇所だけとなります。

具体例を挙げると次のようになります。 次のコードは、1から10までの数値について、(奇数ではなく)素数か偶数かに分類するものです。

' 1から10までの値をSelect Caseで分類する
For i As Integer = 1 To 10

  Select Case i

    Case 2, 3, 5, 7
      Console.WriteLine("{0} は素数です。", i)

    Case 2, 4, 6, 8, 10
      Console.WriteLine("{0} は偶数です。", i)

    Case Else
      Console.WriteLine("{0} は偶数でも素数でもありません。", i)

  End Select

Next
実行結果
1 は偶数でも素数でもありません。
2 は素数です。
3 は素数です。
4 は偶数です。
5 は素数です。
6 は偶数です。
7 は素数です。
8 は偶数です。
9 は偶数でも素数でもありません。
10 は偶数です。

この実行結果から分かるとおり、偶数でも素数でもある2はただ単に「素数である」とだけ表示され、「偶数である」とは表示されません。

Caseの省略

Select Caseステートメントは、Caseを省略して単にSelectと記述することもできます。 従って、次の二つのSelectステートメントはどちらも同等のものとなります。

' Caseを省略しない例
Select Case i

  Case 2, 4, 6, 8, 10
    Console.WriteLine("{0} は偶数です。", i)

  Case Else
    Console.WriteLine("{0} は偶数ではありません。", i)

End Select

' Caseを省略した例
Select i

  Case 2, 4, 6, 8, 10
    Console.WriteLine("{0} は偶数です。", i)

  Case Else
    Console.WriteLine("{0} は偶数ではありません。", i)

End Select

文字列の分類

Select Caseステートメントでは数値だけでなく文字列の分類にも使うことができます。

Dim s As String = "Alice"

Select s

  Case "Alice", "Eve"
    Console.WriteLine("女性名")

  Case "Bob", "Charlie", "Dave"
    Console.WriteLine("男性名")

  Case Else
    Console.WriteLine("未分類・その他")

End Select

Case句と条件式

Case句では分類したい値をカンマで区切る他にも条件式を記述することができます。 値がある範囲にあるかどうかで分類したい場合はToを使うことができます。 例えばX以上Y以下の範囲の値を分類したい場合はX To Yと記述します。

Toで値を分類する例
For i  As Integer = 1 To 10

  Select Case i

    Case 2 To 5
      Console.WriteLine("{0} は2〜5の値です。", i)

    Case 6 To 9
      Console.WriteLine("{0} は6〜9の値です。", i)

    Case Else
      Console.WriteLine("{0} は分類されなかった値です。", i)

  End Select

Next
実行結果
1 は分類されなかった値です。
2 は2〜5の値です。
3 は2〜5の値です。
4 は2〜5の値です。
5 は2〜5の値です。
6 は6〜9の値です。
7 は6〜9の値です。
8 は6〜9の値です。
9 は6〜9の値です。
10 は分類されなかった値です。

比較演算子を使って値を分類したい場合は、Toの代わりにIsを使うことができます。 例えばX未満の値を分類したい場合はIs < Xと記述します。 同様に、X以外の値を分類したい場合はIs <> Xと記述します。 分類条件はCase句が記述されている順(上から順)に評価されるため、複雑な条件を記述する場合は注意が必要です。

Is + 比較演算子で値を分類する例
For i  As Integer = 1 To 10

  Select Case i

    Case Is < 5
      Console.WriteLine("{0} は5未満の値です。", i)

    Case Is >= 8
      Console.WriteLine("{0} は8以上の値です。", i)

    Case Is <> 6
      Console.WriteLine("{0} は5以上8未満、かつ6以外の値です。", i)

    Case Else
      Console.WriteLine("{0} は分類されなかった値です。", i)

  End Select

Next
実行結果
1 は5未満の値です。
2 は5未満の値です。
3 は5未満の値です。
4 は5未満の値です。
5 は5以上8未満、かつ6以外の値です。
6 は分類されなかった値です。
7 は5以上8未満、かつ6以外の値です。
8 は8以上の値です。
9 は8以上の値です。
10 は8以上の値です。

ToIsを使った条件式も、カンマで区切ることにより1つのCase句で複数個記述することができます。 ただし、カンマで区切った場合は条件式は左から順に評価され、かつショートサーキットによる評価が行われる点に注意が必要です。 つまり、1つのCase句に複数個の条件式が記述されていて、なおかつその途中に一致する条件式があった場合は、それ以降の条件式は評価されません。

さらに、ToIsでは範囲に具体的な数値を指定する代わりに、変数や定数を指定することもできます。

ToおよびIsの条件式に変数の値を使う例
Dim min As Integer = 3
Dim max As Integer = 7

For i  As Integer = 1 To 10

  Select Case i

    Case min To max
      Console.WriteLine("{0} は {1} から {2} 以内の値です。", i, min, max)

    Case Else
      Console.WriteLine("{0} は {1} から {2} 以外の値です。", i, min, max)

  End Select

Next

Console.WriteLine()

For i  As Integer = 1 To 10

  Select Case i

    Case Is <= min
      Console.WriteLine("{0} は {1} 以下の値です。", i, min)

    Case Is >= max
      Console.WriteLine("{0} は {1} 以上の値です。", i, max)

    Case Else
      Console.WriteLine("{0} は {1} より大きく {2} より小さい値です。", i, min, max)

  End Select

Next
実行結果
1 は 3 から 7 以外の値です。
2 は 3 から 7 以外の値です。
3 は 3 から 7 以内の値です。
4 は 3 から 7 以内の値です。
5 は 3 から 7 以内の値です。
6 は 3 から 7 以内の値です。
7 は 3 から 7 以内の値です。
8 は 3 から 7 以外の値です。
9 は 3 から 7 以外の値です。
10 は 3 から 7 以外の値です。

1 は 3 以下の値です。
2 は 3 以下の値です。
3 は 3 以下の値です。
4 は 3 より大きく 7 より小さい値です。
5 は 3 より大きく 7 より小さい値です。
6 は 3 より大きく 7 より小さい値です。
7 は 7 以上の値です。
8 は 7 以上の値です。
9 は 7 以上の値です。
10 は 7 以上の値です。

Case句でメソッドを呼び出し、その戻り値をもとに分類することもできます。 以下の例はCase句でメソッドを呼び出す例ですが、このようなSelect Caseステートメントの使用法は読みやすさ・分かりやすさの観点から言えば推奨できるものではありません。 あくまでこういった使用法もできるという1つの例であり、このような場合はSelect CaseではなくIf Elseを使用すべきです。

Dim str As String = "ABC,123.あいう、123日本語。"

For Each ch As Char In str

  ' 戻り値がTrueになるようなメソッドを分類する
  Select Case True

    Case Char.IsLetter(ch)
      Console.WriteLine("{0} は文字です", ch)

    Case Char.IsDigit(ch)
      Console.WriteLine("{0} は数字です", ch)

    Case Char.IsPunctuation(ch)
      Console.WriteLine("{0} は区切り文字です", ch)

    Case Else
      Console.WriteLine("{0} はそれ以外の文字", ch)

  End Select

Next
実行結果
A は文字です
B は文字です
C は文字です
, は区切り文字です
1 は数字です
2 は数字です
3 は数字です
. は区切り文字です
あ は文字です
い は文字です
う は文字です
、 は区切り文字です
1 は数字です
2 は数字です
3 は数字です
日 は文字です
本 は文字です
語 は文字です
。 は区切り文字です

Exit Selectステートメント

Case句による分類後に処理を中断してSelectステートメントから脱出するには、Exit Selectステートメントを使います。

Selectステートメントから脱出する例
For i As Integer = 1 To 10

  Select Case i

    Case 1 To 7
      If i Mod 2 = 0 Then Exit Select

      Console.WriteLine("{0} は1〜7の範囲にある奇数の数値です。", i)

    Case Else
      Console.WriteLine("{0} はそれ以外の数値です。", i)

  End Select

Next
実行結果
1 は1〜7の範囲にある奇数の数値です。
3 は1〜7の範囲にある奇数の数値です。
5 は1〜7の範囲にある奇数の数値です。
7 は1〜7の範囲にある奇数の数値です。
8 はそれ以外の数値です。
9 はそれ以外の数値です。
10 はそれ以外の数値です。

他のCase句へのジャンプ

C#のswitch文ではgoto caseやgoto defaultを使うことで他のラベル(Case句)へジャンプすることができますが、VBではそれに相当する構文は用意されていません。 代わりに通常のGoToステートメントを使用し、他のCase句に設定したラベルへとジャンプさせます。

For i As Integer = 1 To 10

  Select Case i

    Case 1 To 7
      If i Mod 2 = 0 Then GoTo OtherNumber

      Console.WriteLine("{0} は1〜7の範囲にある奇数の数値です。", i)

    Case Else
OtherNumber:
      Console.WriteLine("{0} はそれ以外の数値です。", i)

  End Select

Next
実行結果
1 は1〜7の範囲にある奇数の数値です。
2 はそれ以外の数値です。
3 は1〜7の範囲にある奇数の数値です。
4 はそれ以外の数値です。
5 は1〜7の範囲にある奇数の数値です。
6 はそれ以外の数値です。
7 は1〜7の範囲にある奇数の数値です。
8 はそれ以外の数値です。
9 はそれ以外の数値です。
10 はそれ以外の数値です。