MethodInfo.Invoke调用实例方法必须传入目标对象,传null会抛TargetException;静态方法才允许传null。泛型方法需先用MakeGenericMethod构造封闭类型,参数类型不匹配需显式转换,性能差建议缓存委托。

MethodInfo.Invoke 调用实例方法必须传入目标对象
直接对实例方法调用 MethodInfo.Invoke(null, args) 会抛出 TargetException: Object reference not set to an instance of an object。这是因为实例方法隐含一个 this 参数,反射必须知道调用在哪个对象上。
正确做法是先获取实例(比如 new 出来或从容器中取),再把该实例作为第一个参数传给 Invoke:
var obj = new Calculator();
var method = typeof(Calculator).GetMethod("Add");
var result = method.Invoke(obj, new object[] { 5, 3 }); // 返回 8
- 静态方法才允许传
null作第一个参数 - 若目标对象为
null且方法非静态,异常发生在运行时,编译不报错 - 泛型方法需先用
MakeGenericMethod构造封闭类型,再调用Invoke
参数类型不匹配会导致 TargetParameterCountException 或 ArgumentException
Invoke 不自动做类型转换,哪怕数值上兼容(如传 int 给 long 参数)也会失败。错误信息通常是 System.ArgumentException: Object of type 'System.Int32' cannot be converted to type 'System.Int64'。
解决方式是显式转换参数数组:
var args = new object[] { (long)5, (long)3 };
method.Invoke(obj, args);
- 使用
Convert.ChangeType(value, paramType)可适配更多类型组合 - 注意值类型装箱后仍是原类型,不会“升级”成父类型
- 如果参数含
ref或out,对应位置必须传object引用(如new object[] { refVar }),且调用后需手动解包
性能差、异常多,别在热路径里反复用 MethodInfo.Invoke
每次 Invoke 都要校验访问权限、参数个数、类型兼容性、执行上下文等,开销远高于直接调用。实测比直接调用慢 50–100 倍以上。
本程序版权归作者所有不得利用本程序从事任何非法活动!本程序功能有限只能满足基础型企业网站的建站需求,无法满足更搞要求的企业站,也无法利用本程序制作门户网站,更不能建站购物站。为了克服以上技术局限,我们开发了“新坐标CMS-超级云端网站管理系统”,可以满足任何要求的企业网站,也可以制作购物网站,同时还可以制作门户型网站。其标签式调用方法让您随心所欲调用想要的结果。 使用说明:根目录包含netbox无
高频场景建议缓存委托:
var del = (Func)Delegate.CreateDelegate( typeof(Func ), obj, method); var result = del(5, 3); // 快,且类型安全
-
Delegate.CreateDelegate仅支持公开实例/静态方法;私有方法需用BindingFlags.NonPublic并确保有权限 - .NET 5+ 推荐用
DynamicMethod或表达式树生成委托,更灵活 - 若只是偶尔调用(如插件加载、配置驱动逻辑),
Invoke完全够用,不必过度优化
调用泛型方法前必须先构造具体类型
直接对开放泛型方法(如 List)调用 Invoke 会失败,因为 CLR 不允许执行未闭合的泛型签名。
必须用 MakeGenericMethod 显式指定类型参数:
var list = new List(); var method = typeof(List ).GetMethod("Add"); // 注意:这里 method 已是 closed 类型,可直接 Invoke method.Invoke(list, new object[] { "hello" }); // 若只有开放泛型类型(如 typeof(List<>)),则: var openMethod = typeof(List<>).GetMethod("Add"); var closedMethod = openMethod.MakeGenericMethod(typeof(string)); closedMethod.Invoke(list, new object[] { "world" });
-
MakeGenericMethod返回新MethodInfo,原对象不变 - 泛型约束(如
where T : class)会在MakeGenericMethod时检查,不满足则抛ArgumentException - 泛型类型参数不能是
var或运行时才知的Type变量——必须在调用前确定
Invoke,很容易因隐式类型丢失崩掉。







