クラスに実装されるのメンバーを取得する
About
あるクラスやそのインスタンスに実装されているメンバー(メソッドやフィールド、プロパティ)を取得します。GUIプログラミングで利用することが多そうです。
HowTo
メンバーの取得にはType.GetMembersメソッドを利用します。Typeはtypeofで取得しても良いですし、インスタンスからはGetTypeメソッドを利用して取得することができます。GetMembersメソッドはデフォルトではpublicなメンバーをすべて取得します。
Type type =(typeof(SampleClass)); MemberInfo[] members = type.GetMembers(); foreach(MemberInfo member in members) { Console.WriteLine(member.Name); }
取得したメンバーはMemberInfo型の値として与えられます。ここでは名前Nameを取得していますが、他に取得できる値についてはmsdnなどを参照してください。
デフォルトでは取得するメンバーはpublicなメンバーだけとなりますが、これ以外にprivateやprotectedなメンバーを取得する場合には、BindingFlagsを引数に与えます。BindingFlagsは"|"によって複数指定することができます。
例えばBindingFlags.NonPublicを指定すれば、publicでないメンバーも取得することができるようになります。残りのBindingFlagsについてはmsdn等を参照してください。
MemberInfo[] members = type.GetMembers(BindingFlags.NonPublic|BindingFlags.Instance);
ここで注意しなければならないのは、引数にBindingFlagsを指定する場合、BindingFlags.InstanceないしBindingFlags.Staticを指定しない場合には、いずれの場合にも検索に該当せず、返ってくる配列の長さが0となる点です。Staticなメンバーを取得する場合にはStatic、インスタンスごとに値が定められる一般的なプロパティを取得する場合にはInstanceを必ず指定します。
プロパティだけを取得する
プロパティやフィールドだけを取得したい場合には、それぞれGetPropertiesメソッドやGetFieldsメソッドを使います。コンストラクタなども取得できるので必要であればmsdnなどで確認してください。
set可能なプロパティを検出する
私がプロパティなどを取得して開発を行った時には、setがpublicなプロパティのみを検出する必要がありました。以下のコードで取得したプロパティがpublic.setかどうかを振り分けることができます。propertyはPropertyInfoのインスタンスです。
if (property.CanWrite == false || property.GetSetMethod() == null) //対象のプロパティ(property)のsetはpublicでない;
CanWriteプロパティによって、そのプロパティが書き込み可能かどうかを取得することができます。これは対象のプロパティがsetメソッドを実装していない場合を検知することができます。しかしながらprivateであれprotectedであれ、setメソッドが実行可能な状態にあれば、CanWriteはtrueを返します。そこでGetSetMethodを活用します。GetSetMethodはpublicなsetへのアクセサを返します。
実際にはGetSetMethodのみで必要とする機能は実装できますが、解説のため、CanWriteプロパティも示しています。
BindingFlags.SetPropertyなどの指定では必要な機能を実装することができませんでした。