【C#】リフレクションでプロパティの値を名前(文字列)から動的に取得する方法

通常、C#では obj.Property のようにコンパイル時にプロパティ名が確定している状態でアクセスしますが、ライブラリ開発や汎用的なデータ処理においては、「実行時に文字列で指定されたプロパティの値を取得したい」というケースがあります。

このような動的な型操作を実現するのが**リフレクション(Reflection)**機能です。ここでは System.Reflection 名前空間を使用して、オブジェクトのプロパティ値を名前から取得する実装方法を解説します。

目次

プロパティ値の動的取得の実装

以下のサンプルコードでは、社員情報クラス(Employee)のインスタンスに対し、プロパティ名を文字列(”Name” や “Department”)で指定して値を取り出す汎用メソッドを実装しています。

サンプルコード

using System;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        // 1. データオブジェクトの生成
        var emp = new Employee
        {
            Id = 101,
            Name = "佐藤 健一",
            Department = "開発部"
        };

        // 2. 文字列でプロパティ名を指定して値を取得
        // 通常のアクセス: var name = emp.Name;
        object nameValue = GetPropertyValue(emp, "Name");
        object deptValue = GetPropertyValue(emp, "Department");
        object idValue   = GetPropertyValue(emp, "Id");

        Console.WriteLine($"名前: {nameValue}");
        Console.WriteLine($"部署: {deptValue}");
        Console.WriteLine($"ID  : {idValue}");

        // 存在しないプロパティを指定した場合の挙動確認
        object invalidValue = GetPropertyValue(emp, "Salary");
        if (invalidValue == null)
        {
            Console.WriteLine("指定されたプロパティは見つかりませんでした。");
        }
    }

    /// <summary>
    /// 任意のオブジェクトから、指定された名前のプロパティ値を取得する
    /// </summary>
    /// <param name="targetObj">対象のインスタンス</param>
    /// <param name="propertyName">プロパティ名</param>
    /// <returns>プロパティの値(見つからない場合はnull)</returns>
    public static object GetPropertyValue(object targetObj, string propertyName)
    {
        if (targetObj == null) return null;

        // 1. オブジェクトの型情報(Type)を取得
        Type type = targetObj.GetType();

        // 2. 型情報から指定された名前のプロパティ情報(PropertyInfo)を取得
        // パブリックなインスタンスプロパティを検索します
        PropertyInfo propInfo = type.GetProperty(propertyName);

        // プロパティが存在しない場合は null が返る
        if (propInfo == null)
        {
            return null;
        }

        // 3. 具体的なインスタンス(targetObj)から値を取り出す
        // 引数が不要なプロパティの場合、第2引数は null でよい
        return propInfo.GetValue(targetObj);
    }
}

// サンプル用データクラス
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Department { get; set; }
}

解説と技術的なポイント

1. Type.GetPropertyメソッド

obj.GetType() で取得した Type オブジェクトに対し、GetProperty("プロパティ名") を呼び出すことで、そのプロパティに関するメタデータ(型、読み書き可否など)を持つ PropertyInfo オブジェクトを取得できます。該当するプロパティが存在しない場合は null が返されます。

2. PropertyInfo.GetValueメソッド

取得した PropertyInfo を使って実際に値を取り出すのが GetValue メソッドです。

  • 第1引数: 値を取り出したい実体のインスタンスを指定します。
  • 戻り値: プロパティの型に関わらず object 型として返されるため、必要に応じてキャストして使用します。

3. 注意点:パフォーマンスと可視性

  • 速度: リフレクションを用いたアクセスは、通常の直接アクセスに比べて数十倍〜数百倍遅くなる場合があります。頻繁に(ループ内で数万回など)呼び出す場合は、キャッシュや式木(Expression Tree)の利用を検討してください。
  • アクセス権: type.GetProperty はデフォルトで public なプロパティのみを検索します。private なプロパティにアクセスしたい場合は、BindingFlags を指定する必要があります。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

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

目次