C# 使用反射调用方法(MethodInfo.Invoke方法)传参的问题

2020年02月12日 16:42 0 点赞 0 评论

有同学在使用反射调用方法(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 方法的传参机制了。

作者信息

肉饼

肉饼

共发布了 153 篇文章