列挙型(Enum)をUI(ドロップダウンリストやラベル)に表示する際、コード上の識別子(例:CreditCard)ではなく、ユーザーに分かりやすい日本語の名称(例:”クレジットカード”)を表示したいケースが多々あります。
このような場合、各メンバに [Display] 属性を付与し、リフレクションを使用してその値を取得する方法が標準的です。
目次
Enumの属性取得の実装
以下のサンプルコードでは、支払い方法を表す PaymentMethod 列挙型の各メンバに DisplayAttribute で日本語名を定義し、それを動的に取得して表示しています。
サンプルコード
using System;
using System.ComponentModel.DataAnnotations; // Display属性を使用するために必要
using System.Reflection;
public class Program
{
public static void Main()
{
// 取得したいEnumの値
var selectedMethod = PaymentMethod.BankTransfer;
Console.WriteLine($"コード上の名前: {selectedMethod}");
// 1. Enumの型情報を取得
Type type = selectedMethod.GetType();
// 2. 値に対応するフィールド情報(FieldInfo)を取得
// Enumの値.ToString() でフィールド名("BankTransfer"など)が取れるので、それを使って検索
FieldInfo fieldInfo = type.GetField(selectedMethod.ToString());
if (fieldInfo != null)
{
// 3. フィールドに付与されているDisplayAttributeを取得
// System.Reflection.CustomAttributeExtensions の拡張メソッドを使用
var attribute = fieldInfo.GetCustomAttribute<DisplayAttribute>();
if (attribute != null)
{
// 属性のNameプロパティ(日本語名)を表示
Console.WriteLine($"表示用名称 : {attribute.Name}");
}
}
}
}
// 属性を付与した列挙型(支払い方法)
public enum PaymentMethod
{
[Display(Name = "クレジットカード")]
CreditCard,
[Display(Name = "銀行振込")]
BankTransfer,
[Display(Name = "代金引換")]
CashOnDelivery,
// 属性がない場合
Unknown
}
実行結果
コード上の名前: BankTransfer
表示用名称 : 銀行振込
解説と技術的なポイント
1. EnumとFieldInfoの関係
列挙型の各メンバ(CreditCard 等)は、内部構造としてはその列挙型クラスの 静的フィールド (static field) として定義されています。そのため、クラスのプロパティを取得する GetProperty ではなく、GetField メソッドを使用してメタデータを取得する必要があります。
2. 汎用的な拡張メソッドへの応用
この処理は頻繁に使用されるため、以下のような拡張メソッドとして定義し、.ToDisplayName() のように呼び出せるようにするのが一般的です。
public static class EnumExtensions
{
/// <summary>
/// EnumのDisplay属性のNameを取得する。属性がない場合はToString()を返す。
/// </summary>
public static string ToDisplayName(this Enum value)
{
if (value == null) return string.Empty;
// フィールド情報を取得
var field = value.GetType().GetField(value.ToString());
// 属性を取得
var attribute = field?.GetCustomAttribute<DisplayAttribute>();
// 属性があればNameを、なければそのままの文字列表記を返す
return attribute?.Name ?? value.ToString();
}
}
