C#调用已加载DLL中接口为参数的方法报ArgumentException如何解决?
错误根因
该错误本质是类型身份不匹配,.NET运行时判断两个类型是否相同的依据是「所属程序集完整信息 + 命名空间 + 类型全名」,触发该错误的常见原因有两类:
- 本地项目单独引入的
ICommand接口定义,和MyFile.dll内置的MyFile.ICommand虽然代码结构完全一致,但分属不同程序集,运行时会判定为完全无关的两个类型 - 用
Assembly.LoadFrom加载的程序集属于独立加载上下文,和当前应用域默认上下文的类型体系不互通
解决方案
按优先级从高到低选择:
方案1:直接引用目标DLL(最优)
不要在本地项目单独拷贝接口定义文件,直接将MyFile.dll添加为项目的程序集引用,本地的Command抽象类、GetModel_Command类统一继承自DLL导出的MyFile.ICommand接口,保证类型同源,原有代码无需修改即可正常运行。
方案2:共享接口程序集
如果MyFile.dll为可控制编译的项目,把ICommand、IResponse这类公共接口提取到单独的类库项目中,应用项目和MyFile.dll项目共同引用这个公共接口类库,保证接口的定义来源唯一,即可避免类型冲突。
方案3:反射适配调用(仅适用于无法引用DLL的动态加载场景)
如果不能直接引用MyFile.dll,可以通过反射构造符合DLL接口约定的参数,或者使用dynamic跳过静态类型检查,示例代码如下:
Assembly assembly = Assembly.LoadFrom("MyFile.dll"); Type handlerType = assembly.GetType("MyFile.CommandHandler"); object instance = Activator.CreateInstance(handlerType); // 使用dynamic跳过静态类型检查,仅当GetModel_Command的成员和MyFile.ICommand定义完全匹配时生效 dynamic dynamicInstance = instance; dynamic command = new GetModel_Command(); dynamic result = dynamicInstance.ProcessCommand(command);
内容的提问来源于stack exchange,提问作者Gismail
相关产品推荐
相关产品推荐

