【C#】型に含まれるプロパティ一覧を動的に取得する方法(GetPropertiesとBindingFlags)

C#のリフレクション機能を使用すると、コンパイル時には不明なクラスの構造(プロパティやメソッド)を実行時に解析できます。

特に Type.GetProperties メソッドは、オブジェクトが持っているプロパティの一覧を取得する際によく使用されます。

このメソッドを使用する際、検索対象を絞り込むための BindingFlags 列挙体の理解が不可欠です。ここでは、主要なフラグの意味と、実際のコードでの使用例を解説します。

目次

BindingFlagsの主なフィールド

GetProperties メソッドの引数にこれらのフラグをビット演算(OR |)で組み合わせて渡すことで、取得したいプロパティの範囲(publicのみ、staticも含めるなど)を制御できます。

フィールド意味
Instanceインスタンスメンバー(static が付いていないもの)を検索対象に含めます。
Static静的メンバー(static が付いているもの)を検索対象に含めます。
Public公開メンバー(public)を検索対象に含めます。
NonPublic非公開メンバー(private, protected, internal)を検索対象に含めます。
DeclaredOnly親クラスから継承したメンバーを除外し、そのクラスで独自に宣言されたメンバーのみを検索対象とします。

注意: Instance または Static のいずれか(あるいは両方)と、Public または NonPublic のいずれか(あるいは両方)を必ず指定する必要があります。片方だけでは正しく取得できません。

実装サンプル:プロパティ情報の全取得

以下のコードは、アクセス修飾子やstaticの有無が異なるプロパティを持つ独自クラスを定義し、リフレクションを用いてそれらの情報を抽出する例です。

サンプルコード

using System;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        // 解析対象の型情報を取得
        Type targetType = typeof(AppUser);

        Console.WriteLine($"--- クラス: {targetType.Name} のプロパティ一覧 ---");

        // 検索条件の設定
        // Instance: インスタンスプロパティ
        // Static: 静的プロパティ
        // Public: publicなプロパティ
        // NonPublic: privateなどのプロパティ
        // DeclaredOnly: 継承元(objectクラス等)のプロパティは除外
        var flags = BindingFlags.Instance | 
                    BindingFlags.Static | 
                    BindingFlags.Public | 
                    BindingFlags.NonPublic | 
                    BindingFlags.DeclaredOnly;

        // プロパティ情報の配列を取得
        PropertyInfo[] properties = targetType.GetProperties(flags);

        foreach (var p in properties)
        {
            // プロパティの詳細を表示
            // Name: プロパティ名
            // PropertyType: 型
            // CanRead/CanWrite: get/setの有無
            Console.WriteLine($"名前: {p.Name,-15} | 型: {p.PropertyType.Name,-10} | 読込: {p.CanRead} / 書込: {p.CanWrite}");
        }
    }
}

// 解析対象のサンプルクラス
public class AppUser
{
    // 1. 公開インスタンスプロパティ
    public string UserName { get; set; }

    // 2. 非公開インスタンスプロパティ
    private int InternalId { get; set; }

    // 3. 公開静的プロパティ
    public static string DefaultRole { get; } = "Guest";

    // 4. 読み取り専用プロパティ
    public DateTime CreatedAt { get; }

    public AppUser()
    {
        CreatedAt = DateTime.Now;
    }
}

実行結果

--- クラス: AppUser のプロパティ一覧 ---
名前: UserName        | 型: String     | 読込: True / 書込: True
名前: InternalId      | 型: Int32      | 読込: True / 書込: True
名前: DefaultRole     | 型: String     | 読込: True / 書込: False
名前: CreatedAt       | 型: DateTime   | 読込: True / 書込: False

解説

検索フラグの重要性

GetProperties() を引数なしで呼び出した場合、デフォルトでは 「Public かつ Instance かつ Static」 なプロパティのみが返されます(privateなものは取得できません)。

private なプロパティや、継承されたプロパティを制御したい場合は、サンプルコードのように BindingFlags を明示的に指定する必要があります。

PropertyInfoの活用

取得した PropertyInfo オブジェクトからは、名前や型だけでなく、以下のような詳細情報も確認できます。

  • CanRead, CanWrite: ゲッター(get)、セッター(set)が存在するか。
  • GetCustomAttributes(): プロパティに付与されている属性(Attribute)を取得。
  • GetValue(), SetValue(): 実際に値を取得・設定する。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

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

目次