使用反射创建外部程序集对象时遇MissingMethodException问题求助
解决反射创建带可选参数构造函数对象的MissingMethodException问题
这个坑我之前踩过!核心原因是C#的可选参数只是编译时的语法糖——在IL(中间语言)层面,你的ExternalClass根本没有无参构造函数,只有一个带2个参数的构造函数,那些“可选”的默认值是编译器帮你自动填充的,反射API可不吃这套语法糖,所以直接找无参构造或者只传部分参数的时候就会抛出找不到构造函数的异常。
两种解决方案,看你需求选
方法1:手动传入默认参数值
如果你清楚构造函数里可选参数的默认值,最简单的方式就是直接把这些默认值传给反射调用,模拟编译器帮你做的事:
假设你的ExternalClass构造函数是这样的:
public ExternalClass(string arg1 = "defaultVal", int arg2 = 42) { // ... }
那反射调用就这么写:
// 获取对应参数类型的构造函数 var constructor = typeof(ExternalClass).GetConstructor(new[] { typeof(string), typeof(int) }); // 传入默认值(必须和构造函数定义的一致) var instance = constructor.Invoke(new object[] { "defaultVal", 42 });
或者用更简洁的Activator.CreateInstance:
var instance = Activator.CreateInstance(typeof(ExternalClass), "defaultVal", 42);
方法2:通过反射自动获取默认参数值
如果不想硬编码默认值(比如怕后续构造函数默认值修改),可以通过ParameterInfo自动提取每个参数的默认值:
Type externalType = typeof(ExternalClass); // 这里假设只有一个构造函数,要是有多个,你可以根据参数类型筛选 ConstructorInfo targetCtor = externalType.GetConstructors().First(); // 提取所有参数的默认值,自动组装成参数数组 object[] defaultParams = targetCtor.GetParameters() .Select(param => param.DefaultValue) .ToArray(); // 创建实例 var instance = targetCtor.Invoke(defaultParams);
如果只想传部分自定义参数,其他用默认值也可以:
Type externalType = typeof(ExternalClass); ConstructorInfo targetCtor = externalType.GetConstructor(new[] { typeof(string), typeof(int) }); ParameterInfo[] paramInfos = targetCtor.GetParameters(); object[] paramsArray = new object[paramInfos.Length]; // 第一个参数传自定义值 paramsArray[0] = "myCustomArg"; // 第二个参数用默认值 paramsArray[1] = paramInfos[1].DefaultValue; var instance = targetCtor.Invoke(paramsArray);
为啥直接实例化没问题?
因为C#编译器在编译new ExternalClass()的时候,会偷偷把代码转换成new ExternalClass("defaultVal", 42),相当于帮你自动填充了默认值。但反射是直接操作IL层面的构造函数,它看到的只有那个带2个参数的构造函数,自然找不到你以为的“无参构造”啦。
内容的提问来源于stack exchange,提问作者YogoWafel
相关产品推荐
相关产品推荐

