Type.InvokeMemberメソッドを使うと型情報とメンバ名によってメンバの呼び出しを行うことができます。

InvokeMemberメソッドでは、メソッドの呼び出しのほか、プロパティの値の取得・設定、フィールドの値の取得・設定を行うことができます。 またコンストラクタを呼び出すことによってインスタンスを作成することもできます。 呼び出すメンバに応じて、次のBindingFlagsのいずれかを指定します。

InvokeMemberメソッドとBindingFlags
BindingFlags InvomeMemberメソッドの動作
BindingFlags.InvokeMethod メソッドの呼び出し
指定した名前・引数と一致するメソッドを呼び出して戻り値を取得する
BindingFlags.SetProperty プロパティの設定
指定した名前のプロパティに値を設定する
BindingFlags.GetProperty プロパティの取得
指定した名前のプロパティの値を取得する
BindingFlags.SetField フィールドの設定
指定した名前のフィールドに値を設定する
BindingFlags.GetField フィールドの取得
指定した名前のフィールドの値を取得する
BindingFlags.CreateInstance コンストラクタの呼び出し
指定した引数と一致するコンストラクタを呼び出してインスタンスを作成する

これらの値に加えて、非パブリックメンバを呼び出したり、メンバ名の大文字小文字の違いを無視して呼び出せるようにするためにBindingFlags.NonPublicやBindingFlags.IgnoreCaseなどを組み合わせて指定することもできます。

InvokeMemberメソッドでは、引数targetに操作の対象となるインスタンスを指定します。 静的メンバ(static/Shared)の場合は、インスタンスの代わりにnull/Nothingを指定します。

メソッドおよびコンストラクタの呼び出し時に渡す引数や、フィールド・プロパティに設定する値は、引数argsobject型の配列に格納した上で指定します。 引数がない場合はnull/Nothingを指定することができます。

また、BindingFlags.InvokeMethodで呼び出したメソッドの戻り値や、BindingFlags.CreateInstanceで作成したインスタンス、BindingFlags.GetPropertyおよびBindingFlags.GetFieldで取得したプロパティ・フィールドの値はInvokeMemberメソッドの戻り値として取得することができます。

Type.InvokeMemberを使ってインスタンスの作成を行う
using System;
using System.Reflection;

class C {
  private string str = "Hello, world!";

  public C()
  {
  }

  public C(string str)
  {
    this.str = str;
  }

  public override string ToString()
  {
    return str;
  }
}

class Sample {
  static void Main()
  {
    var t = typeof(C);

    object inst;

    // コンストラクタに渡す引数を指定せずにインスタンスを作成する
    // (引数のないコンストラクタを使ってインスタンスを作成する)
    inst = t.InvokeMember(null, BindingFlags.CreateInstance, null, null, null);

    Console.WriteLine(inst);

    // コンストラクタに渡す引数を指定してインスタンスを作成する
    // (引数のあるコンストラクタを使ってインスタンスを作成する)
    inst = t.InvokeMember(null, BindingFlags.CreateInstance, null, null, new object[] {"Hello, instance!"});

    Console.WriteLine(inst);
  }
}
実行結果
Hello, world!
Hello, instance!

ジェネリック型のメソッドあるいはジェネリックメソッドを呼び出す場合については、§.ジェネリック型のメソッド・ジェネリックメソッドを参照してください。

メンバ呼び出しの結果例外が発生した場合、例外はTargetInvocationExceptionにラップされた上でスローされます。 TargetInvocationExceptionから実際にスローされた例外を取得する方法については§.TargetInvocationException、TargetInvocationExceptionにラップせずにスローさせる方法については§.BindingFlags.DoNotWrapExceptionsを参照してください。

MENTAにてテキストチャットによるサポートを行っています。 問題の解決法をお探しの方や.NET/C#を学習中の方はどうぞご利用ください。