后期绑定场景下编译器要求引用未直接依赖类库的原因求助
问题底层原理说明
1. 调用返回MathOperations的方法报错的原因
这个报错和你是否用Object类型接收返回值、是否用后期绑定没有关系,问题出在方法签名的编译校验阶段:
- .NET编译器处理外部程序集的方法调用时,首先需要完整解析该方法的全部元数据,包括返回值类型、参数类型、所有关联的类型定义。
- 你调用的
Factory.createMathsObject()方法的返回类型是MathOperations,这个类型定义在未被C项目引用的MyMathsLibrary.dll中,编译器无法获取到该类型的元数据,连方法签名本身都无法完成合法性校验,直接在方法调用这一步就触发编译错误,还没到处理返回值赋值给Object变量的步骤。
注:哪怕你不接收该方法的返回值,只写一行
Factory.createMathsObject(),编译也会报同样的错误,和返回值如何使用无关。
2. 返回类型改为Object后报错消失的原因
当你把B项目中createMathsObject的返回类型改为Object后:
- 方法签名中所有涉及的类型里,
Object属于.NET runtime默认引用的核心程序集类型,编译器可以正常解析方法的全部元数据,方法调用的校验通过。 - 后续你将返回值赋值给
Object类型的m,调用m.ADD属于VB.NET的后期绑定特性(默认关闭Option Strict时允许),后期绑定的成员校验会推迟到运行时由CLR完成,编译期不需要校验MathOperations类型的成员信息,因此整个编译流程可以正常通过。 - 运行时CLR会自动加载被B依赖的
MyMathsLibrary.dll,动态查找ADD方法执行,所以代码可以正常运行。
补充说明
如果你不想让C项目直接引用A,也不想返回Object丢失类型安全性,可以将MathOperations的公共接口提取到独立的共享类库中,A实现该接口,B的工厂方法返回接口类型,C只需要引用共享接口类库即可,不需要直接引用A。
内容的提问来源于stack exchange,提问作者Sougata
相关产品推荐
相关产品推荐

