列挙型と数値の互換性
C#の列挙型(enum)は、内部的には整数(デフォルトではint)として扱われています。データベースへの保存時や、外部APIとの通信時など、可読性の高いenumを数値に変換したり、逆に数値からenumに戻したりする操作は頻繁に発生します。
この記事では、キャスト(型変換)を使用した相互変換の方法と、変換時に未定義の値が含まれる場合の対策について解説します。
1. 列挙型から数値への変換 (enum -> int)
列挙型の値を対応する整数値として取得するには、明示的なキャスト (int) を使用します。
int numericValue = (int)EnumType.Value;
コード例:ステータスコードの取得
配送状況を表すDeliveryStatus列挙型を定義し、その値をデータベース保存用に整数化する例です。
using System;
public class EnumToIntExample
{
public static void Main()
{
// 現在のステータス
DeliveryStatus currentStatus = DeliveryStatus.Shipped;
// enum を int にキャスト (変換)
int statusCode = (int)currentStatus;
Console.WriteLine($"ステータス名: {currentStatus}");
Console.WriteLine($"保存する数値: {statusCode}");
}
}
// 配送ステータス
public enum DeliveryStatus
{
Pending = 10,
Processing = 20,
Shipped = 30,
Delivered = 40
}
出力結果:
ステータス名: Shipped
保存する数値: 30
2. 数値から列挙型への変換 (int -> enum)
逆に、整数値を列挙型に戻す場合も、明示的なキャスト (EnumType) を使用します。
EnumType enumValue = (EnumType)intValue;
コード例:数値からの復元
データベースから読み込んだ数値(40)を、プログラムで扱いやすいenum型に変換する例です。
using System;
public class IntToEnumExample
{
public static void Main()
{
// データベースから取得した値と仮定
int dbValue = 40;
// int を enum にキャスト (変換)
DeliveryStatus restoredStatus = (DeliveryStatus)dbValue;
// 変換結果の確認
if (restoredStatus == DeliveryStatus.Delivered)
{
Console.WriteLine($"コード {dbValue} は 'Delivered' (配達完了) です。");
}
else
{
Console.WriteLine($"その他のステータス: {restoredStatus}");
}
}
}
出力結果:
コード 40 は 'Delivered' (配達完了) です。
重要な注意点:未定義の値へのキャスト
C#の仕様では、列挙型に定義されていない数値であっても、強制的にキャストすることが可能です。これはバグの温床となりやすいため注意が必要です。
例えば、DeliveryStatusには99という値は定義されていませんが、(DeliveryStatus)99というコードはエラーにならず、そのまま実行されます。
int invalidCode = 99;
DeliveryStatus status = (DeliveryStatus)invalidCode;
Console.WriteLine(status); // "99" と出力される(列挙型の名前にはならない)
解決策:Enum.IsDefined によるチェック
数値がその列挙型に定義されている正しい値かどうかを検証するには、Enum.IsDefinedメソッドを使用します。
using System;
public class EnumValidationExample
{
public static void Main()
{
int inputCode = 99; // 定義されていない不正な値
// 値が DeliveryStatus に定義されているか確認
if (Enum.IsDefined(typeof(DeliveryStatus), inputCode))
{
DeliveryStatus validStatus = (DeliveryStatus)inputCode;
Console.WriteLine($"有効なステータスです: {validStatus}");
}
else
{
Console.WriteLine($"エラー: コード {inputCode} は DeliveryStatus に存在しません。");
}
}
}
出力結果:
エラー: コード 99 は DeliveryStatus に存在しません。
まとめ
列挙型と数値型の相互変換は、キャスト演算子 (type) を使用して簡単に行うことができます。
enum->int:(int)valueで数値を取得します。int->enum:(EnumType)numberで列挙型に戻します。- 安全性: 定義されていない数値も変換できてしまうため、外部からの入力を変換する場合は
Enum.IsDefinedで妥当性を検証することが推奨されます。
