ある型(クラス、値型、配列、インターフェイス、ポインタ、列挙体)のすべてのメンバを取得する方法は、「型のすべてのメンバを取得する」で紹介しました。
ある型の指定した名前のメンバを取得するには、TypeクラスのGetMemberメソッドを使います。このとき、メンバの名前、メンバ型(プロパティ、メソッド、フィールドなど)、BindingFlags(詳しくはこちら)を指定することができます。
以下に、Stringクラスの"To"で始まる非静的なパブリックメソッドを検索する例を示します。
'Imports System.Reflection 'がソースファイルの一番上に書かれているものとする 'StringクラスのTypeオブジェクトを取得する Dim t As Type = GetType(System.String) '"To"ではじまるメソッドを検索する 'IgnoreCaseにより、大文字小文字を区別しないで検索 Dim members As MemberInfo() = t.GetMember( _ "To*", MemberTypes.Method, _ BindingFlags.Public Or BindingFlags.Instance Or _ BindingFlags.DeclaredOnly Or BindingFlags.IgnoreCase) Dim m As MemberInfo For Each m In members 'メンバの名前を表示する Console.WriteLine(m.Name) Next
//using System.Reflection; //がソースファイルの一番上に書かれているものとする //StringクラスのTypeオブジェクトを取得する Type t = typeof(System.String); //"To"ではじまるメソッドを検索する //IgnoreCaseにより、大文字小文字を区別しないで検索 MemberInfo[] members = t.GetMember("To*", MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase); foreach (MemberInfo m in members) { //メンバの名前を表示する Console.WriteLine(m.Name); }
実行した結果は次のようになります。
ToString ToString ToCharArray ToCharArray ToLower ToLower ToUpper ToUpper
型のプロパティ、メソッド、フィールド、コンストラクタ、インターフェイス、イベント、入れ子になっている型を検索するには、それぞれ、GetProperty、GetMethod、GetField、GetInterface、GetEvent、GetNestedTypeメソッドを使用します。
次にGetMethodメソッドを使用した例を示します。ここでは、StringクラスにConcatという名前でパラメータが(string, string)の静的パブリックメソッドがあるか検索しています。ちなみにGetMethodメソッドを呼び出したとき、複数のメソッドが見つかった時は、例外AmbiguousMatchExceptionがスローされます。
'Imports System.Reflection 'がソースファイルの一番上に書かれているものとする 'StringクラスのTypeオブジェクトを取得する Dim t As Type = GetType(System.String) 'Concatという名前でパラメータが(string, string)の '静的パブリックメソッドを探す Dim method As MethodInfo = t.GetMethod("Concat", _ BindingFlags.Public Or BindingFlags.Static, _ Nothing, _ New Type() {GetType(String), GetType(String)}, _ Nothing) '見つかった時、名前を表示 If Not (method Is Nothing) Then Console.WriteLine(method.Name) Else Console.WriteLine("見つかりませんでした。") End If
//using System.Reflection; //がソースファイルの一番上に書かれているものとする //StringクラスのTypeオブジェクトを取得する Type t = typeof(System.String); //Concatという名前でパラメータが(string, string)の //静的パブリックメソッドを探す MethodInfo method = t.GetMethod("Concat", BindingFlags.Public | BindingFlags.Static, null, new Type[] {typeof(string), typeof(string)}, null); //見つかった時、名前を表示 if (method != null) { Console.WriteLine(method.Name); } else { Console.WriteLine("見つかりませんでした。"); }
TypeクラスのGetMemberメソッド以外にメンバを検索する方法として、FindMembersメソッドを使う方法もあります。FindMembersメソッドはMemberFilterデリゲートにより検索方法を指定できるため、より柔軟な検索ができます。
次にFindMembersメソッドを使って、Stringクラスのメソッドのうち、"Index"という文字列の入っているものを取得しています。
'Imports System.Reflection 'がソースファイルの一番上に書かれているものとする Class MainClass 'エントリポイント Overloads Shared Sub Main() 'StringクラスのTypeオブジェクトを取得する Dim t As Type = GetType(System.String) '"Index"という文字列の入っているメソッドを探す Dim members As MemberInfo() = t.FindMembers( _ MemberTypes.Method, _ BindingFlags.Public Or BindingFlags.Instance, _ New MemberFilter(AddressOf MemberFilterDelegate), _ "Index") '見つかったメソッド名を表示する Dim m As MemberInfo For Each m In members Console.WriteLine(m.Name) Next End Sub 'FindMembersで使用するMemberFilterデリゲート Public Shared Function MemberFilterDelegate( _ ByVal m As MemberInfo, _ ByVal filterCriteria As Object) As Boolean Dim filter As String = CStr(filterCriteria) 'メンバ名にfilterCriteriaが入っているときはTrueを返す If m.Name.IndexOf(filter) < 0 Then Return False Else Return True End If End Function End Class
//using System.Reflection; //がソースファイルの一番上に書かれているものとする class MainClass { //エントリポイント static void Main(string[] args) { //StringクラスのTypeオブジェクトを取得する Type t = typeof(System.String); //"Index"という文字列の入っているメソッドを探す MemberInfo[] members = t.FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance, new MemberFilter(MemberFilterDelegate), "Index"); //見つかったメソッド名を表示する foreach (MemberInfo m in members) { Console.WriteLine(m.Name); } } //FindMembersで使用するMemberFilterデリゲート public static bool MemberFilterDelegate( MemberInfo m, object filterCriteria) { string filter = (string) filterCriteria; //メンバ名にfilterCriteriaが入っているときはTrueを返す if(m.Name.IndexOf(filter) < 0) return false; else return true; } }
FindMembersメソッドで使用するMemberFilterデリゲートにはすでに用意されているものがいくつかあります。
TypeクラスのFilterNameフィールドは、指定した名前のメンバがあるか、ワイルドカード"*"を使って検索するために使用できます。FilterNameIgnoreCaseフィールドも同様ですが、FilterNameが大文字と小文字を区別して検索するのに対して、FilterNameIgnoreCaseは区別しません。
また、FilterAttributeフィールドは、FieldAttributes、MethodAttributes、またはMethodImplAttributes列挙体を指定し、一致するメンバを検索するために使用できます。