通常、メソッドの呼び出しは instance.MethodName() のように記述しますが、プラグインシステムや動的なスクリプト実行など、実行時になるまで呼び出すべきメソッド名が分からないケースがあります。
このような場合、Type.GetMethod と MethodInfo.Invoke を組み合わせることで、メソッド名を文字列で指定して実行することが可能です。
目次
Invokeメソッドによる動的実行の実装
以下のサンプルコードでは、電卓クラス(Calculator)に定義された計算メソッドを、文字列(”Add” や “Multiply”)で指定して呼び出す処理を実装しています。引数もオブジェクト配列として動的に渡します。
サンプルコード
using System;
using System.Reflection;
public class Program
{
public static void Main()
{
// 1. メソッドを持つクラスのインスタンス生成
var calc = new Calculator();
// 2. クラスの型情報を取得
Type targetType = calc.GetType();
Console.WriteLine("--- 動的なメソッド呼び出し ---");
// 例1: Addメソッド(足し算)を呼び出す
// 引数として 10 と 20 を渡す
CallDynamicMethod(targetType, calc, "Add", new object[] { 10, 20 });
// 例2: Subtractメソッド(引き算)を呼び出す
// 引数として 50 と 15 を渡す
CallDynamicMethod(targetType, calc, "Subtract", new object[] { 50, 15 });
// 例3: Multiplyメソッド(掛け算)を呼び出す
CallDynamicMethod(targetType, calc, "Multiply", new object[] { 5, 5 });
// 存在しないメソッドを指定した場合の挙動確認
CallDynamicMethod(targetType, calc, "Divide", new object[] { 100, 2 });
}
/// <summary>
/// 指定された名前のメソッドをリフレクションで実行する
/// </summary>
/// <param name="type">型情報</param>
/// <param name="instance">実行対象のインスタンス</param>
/// <param name="methodName">メソッド名</param>
/// <param name="args">引数配列</param>
public static void CallDynamicMethod(Type type, object instance, string methodName, object[] args)
{
// 1. メソッド情報を取得 (publicなインスタンスメソッドを検索)
MethodInfo methodInfo = type.GetMethod(methodName);
if (methodInfo == null)
{
Console.WriteLine($"[エラー] メソッド '{methodName}' は見つかりませんでした。");
return;
}
try
{
// 2. メソッドを実行 (Invoke)
// 第一引数: インスタンス, 第二引数: 引数の配列
object result = methodInfo.Invoke(instance, args);
Console.WriteLine($"実行: {methodName}({string.Join(", ", args)}) => 結果: {result}");
}
catch (ArgumentException)
{
Console.WriteLine($"[エラー] '{methodName}' の引数が一致しません。");
}
}
}
// 計算機能を提供するクラス
public class Calculator
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
public int Multiply(int a, int b) => a * b;
// Divideメソッドは意図的に定義していません
}
解説と技術的なポイント
1. Type.GetMethodメソッド
指定した名前を持つ public メソッドの情報を MethodInfo オブジェクトとして取得します。 メソッドのオーバーロード(同名で引数が異なるメソッド)が存在する場合は、このメソッドだけでは特定できないため、引数の型を指定する別のオーバーロード(GetMethod(string name, Type[] types))を使用する必要があります。
2. MethodInfo.Invokeメソッド
取得したメソッド情報に基づいて、実際に処理を実行します。
- 第一引数 (
obj): メソッドを実行する対象のインスタンス。staticメソッドの場合はnullを指定します。 - 第二引数 (
parameters): メソッドに渡す引数をobject型の配列で指定します。引数がないメソッドの場合はnullを渡します。
3. 戻り値の扱い
Invoke メソッドの戻り値は object 型です。呼び出したメソッドの戻り値が void の場合は null が返されます。値を利用する場合は、適切な型へのキャスト((int)result など)が必要です。
