リフレクション

C#文法 リフレクション G01_PropertyInfo

PropertyInfoとは

これまでの章では、ConstructorInfoやMethodInfoを使って、コンストラクタやメソッドといったメンバーの情報をリフレクションで取得する方法を見てきました。この章から扱うPropertyInfoは、その名の通り「プロパティ」に対するリフレクション用のクラスです。クラスに定義されたプロパティの情報を取得し、そのプロパティを通じて値を読み書きすることができます。

題材として、Anderson.DomainプロジェクトにあるStockEntityクラスを使います。StockEntityにはすでにStockIdというプロパティが定義されているので、これをリフレクション経由で操作してみましょう。

フォームにPropertyInfoボタンを配置し、ダブルクリックしてイベントハンドラを作成する

StockEntityクラスにはすでにint型のStockIdプロパティが定義されている

Assembly・Type・インスタンスを用意する

PropertyInfoを取得するには、まずこれまでと同じ手順でAssembly、Type、そして対象クラスのインスタンスを用意する必要があります。これまでの章で何度も登場した、次の3行をそのままコピーして使います。

Assembly.Loadでアセンブリ名からAssemblyを取得し、GetTypeで対象の型(今回はAnderson.Domain.StockEntity)を取得します。そしてActivator.CreateInstanceで、その型のインスタンスを生成します。今回はMailServiceの代わりにStockEntityを対象にするので、型名の部分をStockEntityに書き換えるだけで済みます。

GetPropertyでPropertyInfoを取得する

Assembly・Type・インスタンスの3つが揃ったら、Typeの持つGetPropertyメソッドを使います。GetPropertyの引数には、取得したいプロパティ名を文字列で指定します。今回は“StockId”という文字列を渡します。

プロパティ名を文字列で指定できるということは、たとえば設定ファイルなどにプロパティ名を書いておき、実行時にその文字列を読み込んで動的にアクセス対象のプロパティを切り替える、といった使い方もできるということです。これがリフレクションならではの柔軟性です。

GetPropertyの戻り値はPropertyInfo型なので、変数pで受け取っておきます。

t.GetProperty(“StockId”)でPropertyInfoを取得する。IntelliSenseにも指定した名前を持つpublicプロパティを検索する、と説明が表示される

PropertyInfo p = t.GetProperty(“StockId”); という1行にまとめる

GetValueで値を取得する

PropertyInfoの基本的な使い方は、値を取得するか、値を設定するかのどちらかです。値を取得するときはGetValueメソッドを使います。

動作を確認しやすくするため、StockEntityの初期値として999をセットしておきます。GetValueの引数には、どのインスタンスのプロパティ値を取得したいのかを指定する必要があるため、先ほど生成したinstanceを渡します。p.GetValue(instance)とすることで、そのインスタンスが持つStockIdの値を取得できます。

実際に実行してブレークポイントで確認すると、valueに999が取得できていることが分かります。

var value = p.GetValue(instance); を実行すると、valueに999が取得できる

SetValueで値を設定する

値を設定するときはSetValueメソッドを使います。GetValueと同様に対象のインスタンスを指定し、それに加えて設定したい値を渡します。ここではp.SetValue(instance, 123)として、StockIdの値を123に変更してみます。

SetValueを実行したあと、もう一度GetValueでStockIdの値を取得し、value2という変数で受け取ります。1回目のGetValueでは999だったStockIdが、SetValueによって123に変わり、2回目のGetValueではその変更後の値が取得できるはずです。

実際に実行すると、value2に123が取得でき、SetValueによる値の設定が正しく反映されていることが確認できます。

p.SetValue(instance, 123); のあとにGetValueすると、value2には123が取得できる

まとめ

この章では、PropertyInfoを使ってプロパティにアクセスする基本的な方法を解説しました。GetPropertyでプロパティ名を指定してPropertyInfoを取得し、GetValueで値を取得、SetValueで値を設定するという流れは、これまでのConstructorInfoやMethodInfoと同様、非常にシンプルです。プロパティ名を文字列で扱えることを活かして、設定ファイルなどと組み合わせた動的な処理にも応用できる点を覚えておいてください。

リフレクション

はじめに
A01_はじめに
A02_コースの概要
Type
B01_Typeクラスとは
B02_型からTypeを取得する
B03_自前の型からTypeを取得する
B04_インスタンスからTypeを取得する
B05_Typeのインスタンスは1つだけ
Assembly
C01_Assemblyとは
C02_Assemblyの生成_実行中のアセンブリを取得
C03_Assemblyの生成_アセンブリ名で取得
C04_Assemblyの生成_パスを指定して取得
C05_Assemblyの生成_呼び出し元を取得
C06_Assemblyの生成_型から取得
C07_すべての型を取得する
C08_publicな型だけを取得する
C09_名前を指定して型を取得する
C10_メタ情報の取得
インスタンスの生成
D01_インスタンスの生成
D02_インスタンス生成後の具体例
D03_空のコンストラクタがないとエラーになる
D04_Activatorを使ったインスタンスの生成
D05_引数ありのコンストラクタで生成する方法
ConstructorInfo
E01_コンストラクタの情報を取得
E02_パラメータの情報を取得
E03_コンストラクタの情報からインスタンスを生成する
E04_コンストラクタを検索して生成する
E05_public以外のコンストラクタを取得
E06_staticなコンストラクタがある場合の注意点
E07_コンストラクタのアクセスレベルを取得する
MethodInfo
F01_MethodInfo
F02_引数ありのメソッド呼び出し
F03_メソッドがオーバーロードされているときの指定方法
F04_GetMethods
F05_属性で取得する
F06_staticメソッドを呼び出す
F07_戻り値を取得する
PropertyInfo
G01_PropertyInfo
G02_GetProperties
G03_属性を使ったチェック
G04_汎用的なチェックメソッド
G05_CanWrite

FieldInfo
H01_FieldInfo
H02_public以外のFieldInfo

EventInfo
J01_EventInfoとは
J02_AddEventHandler
J03_EventInfoの注意点
J04_RemoveEventHandler

dynamicを利用したリフレクション
K01_dynamicを利用したリフレクション
K02_dynamicを利用したメソッドの呼び方
K03_オーバーライドされたメソッドの呼び出し
K04_メソッドの存在チェック
K05_dynamicを利用したプロパティへのアクセス
K06_dynamicを利用したフィールドへのアクセス
K07_dynamicを利用したイベントへのアクセス