C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#のリフレクションとは?実行時に型情報と属性を取得する方法を解説

C#におけるリフレクション(Reflection)とは、プログラムの実行時に型(クラス・構造体・インターフェースなど)の情報を動的に取得・操作するための仕組みです。通常、コードはコンパイル時に型が確定しますが、リフレクションを使うことで、実行中にアセンブリやメタデータへアクセスし、クラスのメンバー(メソッド・プロパティ・フィールド)や属性(Attribute)の情報を調べることができます。

System.Reflection名前空間

実行中のプログラムのメタデータにアクセスするためのクラス群は、System.Reflection名前空間にまとめられています。この名前空間には、TypeMemberInfoMethodInfoPropertyInfoなど、型情報を扱うための重要なクラスが含まれています。

MemberInfoオブジェクトによる属性の検出

クラスに関連付けられた属性(カスタム属性)を調べるには、まずSystem.ReflectionMemberInfoオブジェクトを初期化する必要があります。

以下のように、対象となるクラスのオブジェクトを設定します。

System.Reflection.MemberInfo info = typeof(MyClass);

typeof()演算子を使うことで、指定したクラスのTypeオブジェクトを取得できます。このオブジェクトに対してGetCustomAttributes()メソッドを呼び出すことで、そのクラスに適用されたすべての属性を取り出せます。

サンプルコード:カスタム属性の取得

次の例では、独自のHelpAttributeクラスを定義し、それをMyClassに適用した上で、リフレクションによって属性情報を取得しています。

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute {
    public readonly string Url;

    public string Topic { // Topicは名前付きパラメータ
        get {
            return topic;
        }

        set {
            topic = value;
        }
    }

    public HelpAttribute(string url) { // urlは位置パラメータ
        this.Url = url;
    }

    private string topic;
}

[HelpAttribute("Information on the class MyClass")]
class MyClass {

}

namespace AttributeAppl {
    class Program {
        static void Main(string[] args) {
            // MyClassのTypeオブジェクトからMemberInfoを取得
            System.Reflection.MemberInfo info = typeof(MyClass);

            // 適用されているすべての属性を取得
            object[] attributes = info.GetCustomAttributes(true);

            for (int i = 0; i < attributes.Length; i++) {
                System.Console.WriteLine(attributes[i]);
            }

            Console.ReadKey();
        }
    }
}

コードのポイント

  • HelpAttributeクラス: System.Attributeを継承して作成されたカスタム属性です。[AttributeUsage(AttributeTargets.All)]により、あらゆるプログラム要素に適用できるようになっています。
  • 位置パラメータと名前付きパラメータ: コンストラクタの引数urlは位置パラメータ、プロパティTopicは名前付きパラメータとして機能します。
  • GetCustomAttributes(true): 引数にtrueを渡すことで、継承された属性も含めて取得します。

実行結果

Information on the class MyClass

このように、Mainメソッド内でリフレクションを使用することで、MyClassに適用されたHelpAttributeの内容を実行時に動的に読み取って表示できています。

リフレクションの主な用途

  • プラグインアーキテクチャの実装(実行時にアセンブリを読み込んで型を発見)
  • シリアライザー/デシリアライザーの実装(オブジェクトの構造を動的に解析)
  • DIコンテナやORMフレームワークでの自動的な依存性解決・マッピング
  • 単体テストフレームワークでのテストメソッドの自動検出

リフレクションは強力な機能である一方、直接呼び出しに比べてパフォーマンス面で不利になる場合があるため、必要な場面に限定して使用することが推奨されます。

  1. C#の動的配列とは?ArrayListを使った動的な配列の作成方法を解説

    動的配列とは、実行時にサイズを自由に拡張できる配列のことです。通常の静的配列は宣言時にサイズが固定されるため、後から要素数を変更することはできません。その点、動的配列は柔軟性が高く、多くの場面で有利になります。C#で配列を動的に作成するには、ArrayListコレクションを使用します。ArrayListは、個別にインデックスアクセスが可能なオブジェクトの順序付きコレクションを表します。動的なメモリ割り当てに対応しており、リストへの要素の追加(Add)、検索、並べ替え(Sort)なども簡単に行えます。C#で動的配列を作成するサンプルコード以下は、C#でArrayListを使って動的に配列を作成す

  2. C#のコンテキストキーワードとは?意味と一覧をわかりやすく解説

    C#のコンテキストキーワードとはC#では、コード内で使用される文脈(コンテキスト)によって特別な意味を持つ識別子が存在します。代表的な例が、プロパティのアクセサーとして使われる「get」や「set」です。このように、特定の場面でのみキーワードとして機能する語を「コンテキストキーワード」と呼びます。コンテキストキーワードは、通常の予約語(class や int など)とは異なり、常に予約されているわけではありません。そのため、変数名やメソッド名などの識別子としても自由に使用できるのが大きな特徴です。コンテキストキーワードの一覧以下は、C#で定義されている主なコンテキストキーワードの一覧です。コン