使用Activator.CreateInstance创建外部DLL实例时遇MissingMethodException
解决Activator.CreateInstance调用外部DLL构造函数的MissingMethodException问题
核心原因分析
- 可选参数的语法糖特性:C#的可选参数是编译时语法糖,IL层面构造函数依然是带参数的定义,反射调用时不能直接按“无参数构造函数”调用,必须匹配实际的参数列表。
- 类型加载上下文不匹配:你代码中直接使用当前项目引用的
Siemens.Engineering.TiaPortalMode枚举值,但加载的是外部独立的DLL文件,两者的Type对象属于不同的加载上下文,导致参数类型不匹配,构造函数无法被识别。
具体解决步骤
方案1:明确获取目标构造函数并调用
从加载的程序集中获取对应类型的构造函数,同时使用该程序集内的枚举类型值作为参数:
Assembly lAssembly = Assembly.Load(File.ReadAllBytes(@"C:\Siemens.Engineering.dll")); // 从加载的程序集中获取TiaPortalMode类型 Type tiaPortalModeType = lAssembly.GetType("Siemens.Engineering.TiaPortalMode"); // 解析枚举值 object withoutUiMode = Enum.Parse(tiaPortalModeType, "WithoutUserInterface"); // 获取TiaPortal类型 Type lType = lAssembly.GetType("Siemens.Engineering.TiaPortal", true, true); // 获取带TiaPortalMode参数的构造函数 ConstructorInfo ctor = lType.GetConstructor(new Type[] { tiaPortalModeType }); if (ctor != null) { return (dynamic)ctor.Invoke(new object[] { withoutUiMode }); } else { throw new InvalidOperationException("目标构造函数未找到"); }
方案2:使用Activator.CreateInstance的重载并指定绑定标志
如果要利用默认参数特性,可以通过指定绑定标志并传递Type.Missing来调用:
Assembly lAssembly = Assembly.Load(File.ReadAllBytes(@"C:\Siemens.Engineering.dll")); Type lType = lAssembly.GetType("Siemens.Engineering.TiaPortal", true, true); // 使用BindingFlags指定实例+公共构造,传递Type.Missing触发默认参数 return (dynamic)Activator.CreateInstance( lType, BindingFlags.Instance | BindingFlags.Public, null, new object[] { Type.Missing }, null);
额外注意事项
- 确保加载的外部DLL与当前项目引用的版本一致,避免因类型定义差异导致的问题。
- 若DLL存在依赖项,需确保所有依赖程序集也能被正确加载(可通过
AssemblyResolve事件处理依赖加载)。
内容的提问来源于stack exchange,提问作者eipalittau
相关产品推荐
相关产品推荐

