はじめに
リフレクションを利用して静的プロパティにアクセスしたいときってありますよね?
(public
ではないプロパティを触りたいときなど)
ググるとやり方はいくらでも出てきますが,それにもかかわらず実際に書いてみると躓いてしまったので,記事として残しておこうと思います。
やり方
ダラダラ書いてもしょうがないので例を示します。
ここでは,別アセンブリ内の静的クラスQiita.MyClass
に定義されているProp
の値を取得します。
当然ですが,Qiita.MyClass
が定義されているアセンブリが参照に追加されている必要があります。
// using System;
// using System.Reflection;
// 別アセンブリ内のクラスは`Type.GetType`では取得できないので,`Assembly.GetType`を利用する。
Type MyClass;
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) // 読み込まれているアセンブリを取得
{
var T = asm.GetType("Qiita.MyClass"); // 目的の型を取得しようとしてみる。
if (T != null) // 取得できなかったら`null`になる。
{
MyClass = T;
break;
}
}
// StaticとNonPublicを両方指定しないといけない。
var info = MyClass.GetProperty("Prop", BindingFlags.Static | BindingFlags.NonPublic);
// ここでも`BindingFlags.Static`が必要。
dynamic val = info.GetValue(MyClass, BindingFlags.Static, null, null, null);
// 取得した`val`で何かする
最後のPropertyInfo.GetValue
の呼び出し時にBindingFlags.Static
を渡さないとArgumentException
になってしまいます。
これがわからなかったので時間を溶かしてしまいました。
調べても書いてなかったんだもん
PropertyInfo.GetValue
の戻り値はobject
ですが,dynamic
で受けると適当な型として扱えます。怖いですが……。
まとめ
public
ではないということには理由があるので,リフレクションで強引にアクセスしようとするのはやめましょう。
(パフォーマンス的にもよろしくない)