リフレクションとは?
普段業務でC#を使用していますが、.NETフレームワークにはリフレクションなる機能が存在しているらしい。知らなかった😩
愛用しているPerplexity様に、「C#マスターになるためには必須の知識です」とアドバイスいただきました。
これは入門するしかない!
ということで、まずは公式ドキュメントを見てみましょう。
System.Reflection 名前空間内のクラスを System.Type と共に使用すると、読み込まれたアセンブリについての情報、およびそのアセンブリ内に定義されているクラス、インターフェイス、値型 (つまり、構造体と列挙) などの型を取得できます。 また、リフレクションを使用すると、実行時に型インスタンスを作成したり、作成した型インスタンスを呼び出したり、アクセスしたりできます。
※リンクは記事の最後に載せてます。
名前空間で言うとSystem.Reflection
に存在する機能が該当します。
大きく分けて以下の2点が実現可能みたいですね。
- アセンブリの情報取得(アセンブリ内に定義されてれるオブジェクトの型取得)
- 実行時に型インスタンスの生成、および作成した型へのアクセス
なるほど…
物は試しということでとりあえず使ってみることにします。
アセンブリの情報取得
まずは、アセンブリ情報を格納しているSystem.Reflection.Asembly
を見てみます。
公式ドキュメントの実装例をそのままお借りします。
using System;
using System.Reflection;
// object型のアセンブリ情報を取得して出力
Assembly a = typeof(object).Module.Assembly;
Console.WriteLine(a.FullName);
👇出力内容
System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
カンマ区切りで
"アセンブリ名, バージョン, カルチャ, 公開キートークン"
が取得できていることが確認できますね。
特定の型のコンストラクター情報を取得
コンストラクタがたくさんあるクラスってややこしいですよね。
それもリフレクションを使えば一覧で情報を取得できます。
System.String
のコンストラクタを一覧で見てみましょう。
using System;
using System.Reflection;
// GetConstructor()を使ってstringのコンストラクタ情報を取得
// https://learn.microsoft.com/ja-jp/dotnet/api/system.type.getconstructor?view=net-9.0
ConstructorInfo[] constructorInfos = typeof(string).GetConstructors();
// 一覧で出力
foreach (ConstructorInfo info in constructorInfos)
{
Console.WriteLine(info);
}
👇出力内容
Void .ctor(Char[])
Void .ctor(Char[], Int32, Int32)
Void .ctor(Char*)
Void .ctor(Char*, Int32, Int32)
Void .ctor(SByte*)
Void .ctor(SByte*, Int32, Int32)
Void .ctor(SByte*, Int32, Int32, System.Text.Encoding)
Void .ctor(Char, Int32)
Void .ctor(System.ReadOnlySpan`1[System.Char])
ややこしいコンストラクタの引数が一目瞭然ですね。
.ctor
はコンストラクタを表すそうです。
特定の型のpublicメンバー情報を取得
続いては、System.Reflection.MemberInfo
を使ってみます。
プログラム実行中に任意の型のpublicメンバーを取得できます。
object
に定義されているメンバーを取得してみます。
using System;
using System.Reflection;
// Type.GetMembers()を使ってMemberInfoを取得
// http://learn.microsoft.com/ja-jp/dotnet/api/system.type.getmembers?view=net-9.0
MemberInfo[] memberInfos = typeof(object).GetMembers();
// 一覧で出力
foreach (MemberInfo member in memberInfos)
{
Console.WriteLine(member.Name);
}
👇出力内容
GetType
ToString
Equals
Equals
ReferenceEquals
GetHashCode
.ctor
System.Object
クラスに定義されているpublicメンバーが取得できました👏
ちなみにpublicメンバーという指定だけではなく、同じ方法でメソッド、フィールド、プロパティを分けて取得することもできます。
使用するメソッドは下記の通り。
取得したい情報 | 使用するメソッド |
---|---|
pulicメンバー | GetMenbers() |
メソッド | GetMethods() |
フィールド | GetFields() |
プロパティ | GetProperties() |
代表的な機能
最後に、リフレクションの代表的な機能をまとめておきます。
-
Assembly
アセンブリ定義の読み込み、アセンブリからの型検索、インスタンス生成 -
Module
モジュール内のクラスなどの探索(グローバルメソッドや固有の非グローバルメソッドも可) -
ConstructorInfo
コンストラクターの名前、パラメーター、アクセス修飾子、および実装詳細を探索 -
MethodInfo
メソッドの名前、戻り値の型、パラメータ、アクセス修飾子、および実装の詳細を検出 -
FieldInfo
フィールドの名前、アクセス修飾子、実装の詳細の検出、および値の取得・設定 -
EventInfo
イベントハンドラーの名前、データ型、カスタム属性、宣言型等の探索、およびイベントの追加・削除 -
PropertyInfo
プロパティの名前、データ型、宣言型、リフレクションされた型、読み取り専用・書き込み専用のどちらか等の探索、および値の取得・設定 -
ParameterInfo
パラメーターの名前、データ型、入出力どちらか、メソッドシグネチャ内のパラメータの位置等の探索 -
CustumAttributeInfo
MetadataLoadContext
またはリフレクション専用のコンテキスト (.NET Framework) で作業する際に、カスタム属性に関する情報を検出する
公式ドキュメント