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(): 実際に値を取得・設定する。
