キャストにより整数を列挙体値へ変換する方法と、EnumクラスのTryParse/Parse/IsDefinedメソッドにより文字列を列挙体値へ変換する方法を説明する。
本稿では、列挙体(または列挙型)の列挙子(あるいは列挙メンバー)に該当する整数や文字列から、列挙体の値(=列挙値)に変換する方法を解説する。
なお、列挙体の基本となるEnumクラス(System名前空間)は.NET Frameworkの最初からあるものだが、本稿はそれ以降の内容も含んでいる。サンプルコードをそのまま試すには、Visual Studio 2015(またはそれ以降)が必要である。
整数を列挙体に変換するには、キャストすればよい。
文字列を列挙体に変換するには、EnumクラスのTryParseメソッド/Parseメソッドを使う。
変換後の値が列挙子の1つになることを保証するには、EnumクラスのIsDefinedメソッドで確認する。
実際にサンプルコードで確かめてみよう。
次のコードは、整数を列挙体に変換するコンソールアプリだ。列挙子に該当する整数と該当しない整数をそれぞれキャストする例と、キャストする前にIsDefinedメソッドで確認する方法を示している。
列挙子に該当しない整数もキャストできてしまうので、動作するデバイス内で完結するアプリはともかくとして、Webアプリ(ASP.NET)などではIsDefinedメソッドを使った確認は必須といえるだろう。
using System;
using static System.Console;
class Program
{
enum Era { 明治, 大正, 昭和, 平成, };
static void Main(string[] args)
{
// 整数値は列挙体にキャストできる
Era e1 = (Era)2;
WriteLine($"2→{e1}");
// 出力:2→昭和
// 列挙子にない値でもキャストできてしまう
Era e2 = (Era)4;
WriteLine($"4→{e2}");
// 出力:4→4
// 列挙子に該当する値だけに制限したいときはIsDefinedメソッドで確認する
int n = 3;
if (Enum.IsDefined(typeof(Era), n))
{
Era e3 = (Era)n;
WriteLine($"{n}→{e3}");
// 出力:3→平成
}
int m = 4;
if (!Enum.IsDefined(typeof(Era), m))
{
WriteLine($"{m}はEraの列挙子に該当しません");
// 出力:4はEraの列挙子に該当しません
}
#if DEBUG
ReadKey();
#endif
}
}
Option Strict On
Imports System.Console
Module Module1
Enum Era
明治
大正
昭和
平成
End Enum
Sub Main()
' 整数値は列挙体にキャストできる
Dim e1 As Era = CType(2, Era)
WriteLine($"2→{e1}")
' 出力:2→昭和
' 列挙子にない値でもキャストできてしまう
Dim e2 As Era = CType(4, Era)
WriteLine($"4→{e2}")
' 出力:4→4
' 列挙子に該当する値だけに制限したいときはIsDefinedメソッドで確認する
Dim n As Integer = 3
If ([Enum].IsDefined(GetType(Era), n)) Then
Dim e3 As Era = CType(n, Era)
WriteLine($"{n}→{e3}")
' 出力:3→平成
End If
Dim m As Integer = 4
If (Not [Enum].IsDefined(GetType(Era), m)) Then
WriteLine($"{m}はEraの列挙子に該当しません")
' 出力:4はEraの列挙子に該当しません
End If
#If DEBUG Then
ReadKey()
#End If
End Sub
End Module
なお、上のコード中のEra列挙体は、以降のサンプルコードでも使用する。
.NET Framework 4からは、EnumクラスのTryParseメソッドが利用できる。変換できる文字列は、列挙子の名前と、整数の数字だ。
なお、列挙子に該当しない整数の数字も変換されるので注意してほしい(それを避けるには、前述の整数の例と同様にIsDefinedメソッドで確認する)。
// TryParseメソッドで文字列を変換する(.NET 4から)
Era e5;
if(Enum.TryParse<Era>("大正", out e5))
WriteLine($"「大正」→{e5}");
// 出力:「大正」→大正
if (!Enum.TryParse<Era>("江戸", out e5))
WriteLine($"「江戸」はEraの列挙子に該当しません");
// 出力:「江戸」はEraの列挙子に該当しません
// 整数の数字も変換できる(列挙子に該当しない整数も変換されるので注意)
if (Enum.TryParse<Era>("2", out e5))
WriteLine($"「2」→{e5}");
// 出力:「2」→昭和
if (Enum.TryParse<Era>("4", out e5))
WriteLine($"「4」→{e5}");
// 出力:「4」→4
if (!Enum.TryParse<Era>("3.0", out e5)) // 小数点数は変換できない
WriteLine($"「3.0」はEraの列挙子に該当しません");
// 出力:「3.0」はEraの列挙子に該当しません
' TryParseメソッドで文字列を変換する(.NET 4から)
Dim e5 As Era
If ([Enum].TryParse(Of Era)("大正", e5)) Then
WriteLine($"「大正」→{e5}")
' 出力:「大正」→大正
End If
If (Not [Enum].TryParse(Of Era)("江戸", e5)) Then
WriteLine($"「江戸」はEraの列挙子に該当しません")
' 出力:「江戸」はEraの列挙子に該当しません
End If
' 整数の数字も変換できる(列挙子に該当しない整数も変換されるので注意)
If ([Enum].TryParse(Of Era)("2", e5)) Then
WriteLine($"「2」→{e5}")
' 出力:「2」→昭和
End If
If ([Enum].TryParse(Of Era)("4", e5)) Then
WriteLine($"「4」→{e5}")
' 出力:「4」→4
End If
If (Not [Enum].TryParse(Of Era)("3.0", e5)) Then ' 小数点数は変換できない
WriteLine($"「3.0」はEraの列挙子に該当しません")
' 出力:「3.0」はEraの列挙子に該当しません
End If
なお、カンマで区切った文字列を与えることもできる(次のコード)。これはフラグ列挙体(=Flag属性を付けた列挙体)の場合には望ましい動作だが、通常の列挙体でも同じ動作なので、注意していないと思わぬ結果になるかもしれない。これを避けるには、やはりIsDefinedメソッドで確認する(その例は次のParseメソッドで示す)。
Era e5;
// カンマ区切りで渡すと、bitごとのOR演算の結果で列挙値に変換される
if (Enum.TryParse<Era>("明治, 大正", out e5))
WriteLine($"「明治, 大正」→{e5}"); // 0000 | 0001 → 0001
// 出力:「明治, 大正」→大正
if (Enum.TryParse<Era>("大正, 昭和", out e5))
WriteLine($"「大正, 昭和」→{e5}"); // 0001 | 0010 → 0011
// 出力:「大正, 昭和」→平成
Dim e5 As Era
' カンマ区切りで渡すと、bitごとのOR演算の結果で列挙値に変換される
If ([Enum].TryParse(Of Era)("明治, 大正", e5)) Then
WriteLine($"「明治, 大正」→{e5}") ' 0000 Or 0001 → 0001
' 出力:「明治, 大正」→大正
End If
If ([Enum].TryParse(Of Era)("大正, 昭和", e5)) Then
WriteLine($"「大正, 昭和」→{e5}") ' 0001 Or 0010 → 0011
' 出力:「大正, 昭和」→平成
End If
.NET Framework 4以前は、EnumクラスのParseメソッドを使う。変換できない文字列を与えたときは例外が出るので、try〜catchするか、事前にIsDefinedメソッドで確認する(次のコード)。
// .NET 4以前はParseメソッド
WriteLine($"「大正」→{Enum.Parse(typeof(Era),"大正")}");
// 出力:「大正」→大正
try
{
WriteLine($"「江戸」→{Enum.Parse(typeof(Era), "江戸")}");
}
catch (Exception ex)
{
WriteLine($"「江戸」→{ex.GetType().Name}");
// 出力:「江戸」→ArgumentException
}
WriteLine($"「3」→{Enum.Parse(typeof(Era), "3")}");
// 出力:「3」→平成
// Parseメソッドも、カンマ区切りの文字列に対応
WriteLine($"「大正, 昭和」→{Enum.Parse(typeof(Era), "大正, 昭和")}");
// 出力:「大正, 昭和」→平成
// カンマ区切りの文字列を避けるにはIsDefinedメソッドで確認する(TryParseメソッドも同様)
string s1 = "昭和";
if (Enum.IsDefined(typeof(Era), s1))
WriteLine($"「{s1}」→{Enum.Parse(typeof(Era), s1)}");
// 出力:「昭和」→昭和
string s2 = "大正, 昭和";
if (!Enum.IsDefined(typeof(Era), s2))
WriteLine($"「{s2}」はEraの列挙子に該当しません");
// 出力:「大正, 昭和」はEraの列挙子に該当しません
' .NET 4以前はParseメソッド
WriteLine($"「大正」→{[Enum].Parse(GetType(Era), "大正")}")
' 出力:「大正」→大正
Try
WriteLine($"「江戸」→{[Enum].Parse(GetType(Era), "江戸")}")
Catch ex As Exception
WriteLine($"「江戸」→{ex.GetType().Name}")
' 出力:「江戸」→ArgumentException
End Try
WriteLine($"「3」→{[Enum].Parse(GetType(Era), "3")}")
' 出力:「3」→平成
' Parseメソッドも、カンマ区切りの文字列に対応
WriteLine($"「大正, 昭和」→{[Enum].Parse(GetType(Era), "大正, 昭和")}")
' 出力:「大正, 昭和」→平成
' カンマ区切りの文字列を避けるにはIsDefinedメソッドで確認する(TryParseメソッドも同様)
Dim s1 As String = "昭和"
If ([Enum].IsDefined(GetType(Era), s1)) Then
WriteLine($"「{s1}」→{[Enum].Parse(GetType(Era), s1)}")
' 出力:「昭和」→昭和
End If
Dim s2 As String = "大正, 昭和"
If (Not [Enum].IsDefined(GetType(Era), s2)) Then
WriteLine($"「{s2}」はEraの列挙子に該当しません")
' 出力:「大正, 昭和」はEraの列挙子に該当しません
End If
整数を列挙体に変換するにはキャストすればよい。文字列(整数の数字か列挙子の名前)を列挙体に変換するには、EnumクラスのTryParseメソッド(.NET 4から)/Parseメソッド(.NET 4以前)を使う。いずれも、列挙子が定義されているものだけに厳密に変換したいときは、EnumクラスのIsDefinedメソッドでチェックする。
利用可能バージョン:.NET Framework 1.0以降(サンプルコードにはそれ以降の機能/構文も含む)
カテゴリ:クラス・ライブラリ 処理対象:列挙体
使用ライブラリ:Enumクラス(System名前空間)
関連TIPS:列挙体の値を任意の文字列に変換するには?[C#/VB]
関連TIPS:列挙体の値を列挙するには?
関連TIPS:列挙体の名前を列挙するには?
関連TIPS:列挙体をビット・フィールドとして取り扱うには?[C#、VB]
関連TIPS:構文:クラス名を書かずに静的メソッドを呼び出すには?[C# 6.0]
関連TIPS:VB.NETでクラス名を省略してメソッドや定数を利用するには?
関連TIPS:数値を右詰めや0埋めで文字列化するには?[C#、VB]
関連TIPS:Visual Studioでコンソール・アプリケーションのデバッグ実行時にコマンド・プロンプトを閉じないようにするには?
Copyright© Digital Advantage Corp. All Rights Reserved.