DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

型(クラス、構造体など)のすべてのメンバを取得する

ここでは次のようなクラスが定義されているものとし、このクラスのメンバを取得するものとします。

VB.NET
コードを隠すコードを選択
Namespace MyNamespace
    Public Class TestClass
        '列挙型
        Public Enum PublicEnum
            One
            Two
        End Enum

        'フィールド
        Private PrivateField As Integer

        'プロパティ
        Public ReadOnly Property PublicProperty() As Integer
            Get
                Return PrivateField
            End Get
        End Property

        'コンストラクタ
        Public Sub New(ByVal val As Integer)
            PrivateField = val
        End Sub

        'メソッド
        Public Overloads Function PublicMethod(ByVal str As String) As String
            str = "PublicMethodが呼び出されました。" + str
            Return str
        End Function

        Public Overloads Function PublicMethod() As String
            Return PublicMethod("")
        End Function
    End Class
End Namespace
C#
コードを隠すコードを選択
namespace MyNamespace
{
    public class TestClass
    {
        //列挙型
        public enum PublicEnum
        {
            One,
            Two,
        }

        //フィールド
        private int PrivateField;

        //プロパティ
        public int PublicProperty
        {
            get
            {
                return PrivateField;
            }
        }

        //コンストラクタ
        public TestClass(int val)
        {
            PrivateField = val;
        }

        //メソッド
        public string PublicMethod(string str)
        {
            str = "PublicMethodが呼び出されました。" + str;
            return str;
        }
        public string PublicMethod()
        {
            return PublicMethod("");
        }
    }
}

ある型(クラス、値型、配列、インターフェイス、ポインタ、列挙体)のすべてのメンバ(プロパティ、メソッド、フィールド、イベントなど)を取得するには、TypeクラスのGetMembersメソッドを呼び出します。

上記TestClassクラスのすべてのメンバ(継承されたメンバを除く)を列挙するには、次のようにします。

VB.NET
コードを隠すコードを選択
'Imports System.Reflection
'がソースファイルの一番上に書かれているものとする

'TestClassクラスのTypeオブジェクトを取得する
Dim t As Type = GetType(MyNamespace.TestClass)

'メンバを取得する
Dim members As MemberInfo() = t.GetMembers( _
    BindingFlags.Public Or BindingFlags.NonPublic Or _
    BindingFlags.Instance Or BindingFlags.Static Or _
    BindingFlags.DeclaredOnly)

Dim m As MemberInfo
For Each m In members
    'メンバの型と、名前を表示する
    Console.WriteLine("{0} - {1}", m.MemberType, m.Name)
Next
C#
コードを隠すコードを選択
//using System.Reflection;
//がソースファイルの一番上に書かれているものとする

//TestClassクラスのTypeオブジェクトを取得する
Type t = typeof(MyNamespace.TestClass);

//メンバを取得する
MemberInfo[] members = t.GetMembers(
    BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.Static |
    BindingFlags.DeclaredOnly);
foreach (MemberInfo m in members)
{
    //メンバの型と、名前を表示する
    Console.WriteLine("{0} - {1}", m.MemberType, m.Name);
}

この結果は、次のように表示されます。

Field - PrivateField
Method - get_PublicProperty
Method - PublicMethod
Method - PublicMethod
Constructor - .ctor
Property - PublicProperty
NestedType - PublicEnum

BindingFlags

上記のように検索するメンバの種類を指定するために、BindingFlagsを指定してGetMembersメソッドを呼び出します。GetMembersメソッドでよく使用されるBindingFlagsには次のようなものがあります。

メンバ名 説明
Public パブリックメンバを検索の対象に加える。 16
NonPublic パブリックでないメンバを検索の対象に加える。 32
Instance 非静的メンバ(インスタンスメンバ)を検索の対象に加える。 4
Static 静的メンバを検索の対象に加える。 8
DeclaredOnly 継承されたメンバを検索の対象にしない。 2
FlattenHierarchy 階層構造の上位の静的メンバを検索の対象に加える。 64

GetMembersメソッドをパラメータなしで呼び出したときは、
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static
(つまり、28)を指定したのと同じになります。

先に示したコードで、パラメータを指定しないでGetMembersメソッドを呼び出したとき、その結果は次のようになります。

Method - GetHashCode
Method - Equals
Method - ToString
Method - get_PublicProperty
Method - PublicMethod
Method - PublicMethod
Method - GetType
Constructor - .ctor
Property - PublicProperty
NestedType - PublicEnum

GetProperties、GetMethods、GetFields、GetInterfaces、GetEvents、GetNestedTypesメソッド

ある型のすべてのプロパティ、メソッド、フィールド、コンストラクタ、インターフェイス、イベント、入れ子になっている型を取得するには、それぞれ、GetProperties、GetMethods、GetFields、GetInterfaces、GetEvents、GetNestedTypesメソッドを使用します。使い方は、戻り値が違う以外は、GetMembersメソッドと同じです。

次にGetMethodsメソッドを使った例を示します。ここではTestClassクラスのすべてのメソッドを、そのアクセシビリティ、戻り値、パラメータ情報などとともに表示しています。

VB.NET
コードを隠すコードを選択
'Imports System.Reflection
'がソースファイルの一番上に書かれているものとする

'TestClassクラスのTypeオブジェクトを取得する
Dim t As Type = GetType(MyNamespace.TestClass)

'メソッドの一覧を取得する
Dim methods As MethodInfo() = t.GetMethods( _
    BindingFlags.Public Or BindingFlags.NonPublic Or _
    BindingFlags.Instance Or BindingFlags.Static)

Dim m As MethodInfo
For Each m In methods
    '特別な名前のメソッドは表示しない
    If m.IsSpecialName Then
        GoTo ContinueForEach1
    End If

    'アクセシビリティを表示
    'ここではIs...プロパティを使っているが、
    'Attributesプロパティを調べても同じ
    If m.IsPublic Then
        Console.Write("public ")
    End If
    If m.IsPrivate Then
        Console.Write("private ")
    End If
    If m.IsAssembly Then
        Console.Write("internal ")
    End If
    If m.IsFamily Then
        Console.Write("protected ")
    End If
    If m.IsFamilyOrAssembly Then
        Console.Write("internal protected ")
    End If

    'その他修飾子を表示
    If m.IsStatic Then
        Console.Write("static ")
    End If
    If m.IsAbstract Then
        Console.Write("abstract ")
    Else If m.IsVirtual Then
        Console.Write("virtual ")
    End If

    '戻り値を表示
    If m.ReturnType.Equals(Type.GetType("System.Void")) Then
        Console.Write("void ")
    Else
        Console.Write((m.ReturnType.ToString() + " "))
    End If

    'メソッド名を表示
    Console.Write(m.Name)

    'パラメータを表示
    Dim prms As ParameterInfo() = m.GetParameters()
    Console.Write("(")
    Dim i As Integer
    For i = 0 To prms.Length - 1
        Dim p As ParameterInfo = prms(i)
        Console.Write((p.ParameterType.ToString() + " " + p.Name))
        If prms.Length - 1 > i Then
            Console.Write(", ")
        End If
    Next
    Console.Write(")")

    Console.WriteLine()

ContinueForEach1:
Next
C#
コードを隠すコードを選択
//using System.Reflection;
//がソースファイルの一番上に書かれているものとする

//TestClassクラスのTypeオブジェクトを取得する
Type t = typeof(MyNamespace.TestClass);

//メソッドの一覧を取得する
MethodInfo[] methods = t.GetMethods(
    BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.Static);

foreach (MethodInfo m in methods)
{
    //特別な名前のメソッドは表示しない
    if (m.IsSpecialName)
        continue;

    //アクセシビリティを表示
    //ここではIs...プロパティを使っているが、
    //Attributesプロパティを調べても同じ
    if (m.IsPublic)
        Console.Write("public ");
    if (m.IsPrivate)
        Console.Write("private ");
    if (m.IsAssembly)
        Console.Write("internal ");
    if (m.IsFamily)
        Console.Write("protected ");
    if (m.IsFamilyOrAssembly)
        Console.Write("internal protected ");

    //その他修飾子を表示
    if (m.IsStatic)
        Console.Write("static ");
    if (m.IsAbstract)
        Console.Write("abstract ");
    else if (m.IsVirtual)
        Console.Write("virtual ");

    //戻り値を表示
    if (m.ReturnType == typeof(void))
        Console.Write("void ");
    else
        Console.Write(m.ReturnType.ToString() + " ");

    //メソッド名を表示
    Console.Write(m.Name);

    //パラメータを表示
    ParameterInfo[] prms = m.GetParameters();
    Console.Write("(");
    for (int i = 0; i < prms.Length; i++)
    {
        ParameterInfo p = prms[i];
        Console.Write(p.ParameterType.ToString() + " " + p.Name);
        if (prms.Length - 1 > i)
            Console.Write(", ");
    }
    Console.Write(")");

    Console.WriteLine();
}

結果は次のようになります。

protected virtual void Finalize()
public virtual System.Int32 GetHashCode()
public virtual System.Boolean Equals(System.Object obj)
public virtual System.String ToString()
public System.String PublicMethod(System.String str)
public System.String PublicMethod()
public System.Type GetType()
protected System.Object MemberwiseClone()

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。