【C#】プロパティに付与された属性の設定値を取得する (GetCustomAttribute)

特定のプロパティに付与された属性(Attribute)が存在するかを確認するだけでなく、その属性に設定された具体的な値(例:画面表示用のラベル名、エラーメッセージ、設定値など)を読み取りたいケースがあります。

C#のリフレクションと拡張メソッド GetCustomAttribute<T> を使用することで、属性オブジェクトのインスタンスそのものを取得し、そのプロパティ値にアクセスすることが可能です。

目次

属性値の取得実装

以下のサンプルコードでは、Product クラスのプロパティに付与された [Display(Name="...")] 属性から、日本語の表示名を取り出してコンソールに出力する処理を実装しています。

サンプルコード

using System;
using System.ComponentModel.DataAnnotations; // Display属性用
using System.Reflection;

public class Program
{
    public static void Main()
    {
        // 1. 対象の型情報を取得
        Type type = typeof(Product);

        Console.WriteLine("--- 属性値の取得結果 ---");

        // 2. 各プロパティのDisplay属性値を取得して表示
        // nameof演算子を使うことで、プロパティ名の変更に強くなります
        PrintDisplayName(type, nameof(Product.ProductName));
        PrintDisplayName(type, nameof(Product.UnitPrice));
        
        // (参考) 属性が付いていないプロパティの場合
        PrintDisplayName(type, nameof(Product.StockCount));
    }

    /// <summary>
    /// 指定されたプロパティのDisplay属性のName値を出力する
    /// </summary>
    static void PrintDisplayName(Type type, string propertyName)
    {
        // プロパティ情報を取得
        PropertyInfo prop = type.GetProperty(propertyName);
        
        if (prop == null) return;

        // 3. 属性インスタンスを取得
        // GetCustomAttribute<T>() は、指定した属性が見つかればそのインスタンスを、
        // 見つからなければ null を返します。
        var attr = prop.GetCustomAttribute<DisplayAttribute>();

        if (attr != null)
        {
            // 属性のプロパティ(Name)にアクセス
            Console.WriteLine($"プロパティ: {propertyName,-12} | 表示名: {attr.Name}");
        }
        else
        {
            Console.WriteLine($"プロパティ: {propertyName,-12} | 属性なし");
        }
    }
}

// データクラス
public class Product
{
    // 画面表示用の名前を属性で定義
    [Display(Name = "商品名")]
    public string ProductName { get; set; }

    [Display(Name = "商品単価")]
    public int UnitPrice { get; set; }
    
    // 属性を付けていないプロパティ
    public int StockCount { get; set; }
}

実行結果

--- 属性値の取得結果 ---
プロパティ: ProductName  | 表示名: 商品名
プロパティ: UnitPrice    | 表示名: 商品単価
プロパティ: StockCount   | 属性なし

解説と技術的なポイント

1. GetCustomAttribute<T> メソッド

このメソッドは System.Reflection.CustomAttributeExtensions クラスに含まれる拡張メソッドです。 ジェネリック型引数 T に取得したい属性の型(今回は DisplayAttribute)を指定して呼び出します。 戻り値として属性クラスのインスタンスが返ってくるため、通常のクラスと同じようにドット演算子でプロパティ(attr.Name など)にアクセスできます。

2. nameof 演算子の活用

プロパティ名を文字列リテラル "ProductName" で直接書くことも可能ですが、nameof(Product.ProductName) を使用することで、リファクタリング(名前変更)時の追従漏れを防ぎ、コンパイル時にスペルミスを検出できるようになります。

3. DisplayAttribute について

System.ComponentModel.DataAnnotations 名前空間にある標準的な属性です。 ASP.NET Core MVC や Entity Framework などのフレームワークでは、この属性値を自動的に読み取って、入力フォームのラベルやバリデーションメッセージとして利用する仕組みが組み込まれています。今回のコードは、その「読み取り処理」を自前で実装した形になります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次