C# 使用反射调用方法(MethodInfo.Invoke方法)传参的问题
有同学在使用反射调用方法(MethodInfo.Invoke
方法)进行练习时,遇到了传参报错的问题,错误信息如下:
System.Reflection.TargetParameterCountException: Parameter count mismatch.
刚开始接触 Invoke
方法时,可能对其传参的理解存在偏差。下面我们来看这位同学一开始的代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace App
{
class Program
{
static void Main(string[] args)
{
Type type = null;
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var currentType in assembly.GetTypes())
{
if (currentType.Name == "One")
{
type = currentType;
}
}
}
// Type type = Type.GetType("App.One"); // 如果非加载外部程序集,只是测试用这个简写
var obj = Activator.CreateInstance(type);
MethodInfo test = type.GetMethod("Test");
test.Invoke(obj, null);
Console.ReadKey();
}
}
class One
{
public void Test()
{
Console.WriteLine("aaaaa");
}
}
}
一开始,该同学想执行 One
类中的 Test
方法,结果报了参数错误。后来,他对代码进行了进一步修改,将 test.Invoke(obj, null);
改成了 test.Invoke(obj, new object[]{"aaaaa"});
,同时将 One
类修改为:
class One
{
public void Test(object[] strs)
{
Console.WriteLine(strs[0].ToString());
}
}
该同学可能理解成 Invoke
的第二个参数要与 Test
方法的参数对应,但这样修改后仍然报错。
实际上,正确的理解应该是:Invoke
方法会将第二个参数解析出 Test
方法所需要的参数,然后传入到 Test
方法中。
下面通过具体示例来进一步说明:
- 参数为
new object[]{"bb","cc"}
的情况: 此时Test
方法应该这样写:public void Test(string a, string b) { Console.WriteLine(a); }
- 参数为
new object[]{"bb", 1}
的情况:Test
方法应该这样写:public void Test(string a, int b) { Console.WriteLine(b); }
大家可以将上面的代码进行练习,这样应该就能正确理解 MethodInfo.Invoke
方法的传参机制了。