Mono.Cecil跨程序集解析基类返回null问题的技术问询
使用Mono.Cecil跨程序集解析基类返回null的问题及解决
问题背景
我实现了一个基于Mono.Cecil的方法,用于获取类型的所有成员,该方法会遍历整个类型继承层级。但执行以下代码时,baseType经常返回null:
// asmType 为 TypeDefinition 类型 TypeDefinition baseType = asmType.BaseType.Resolve();
执行前已确认asmType.BaseType不为null,且明确知晓基类确实存在。该问题在基类与派生类位于不同程序集时更容易出现,且两个程序集均在Mono.Cecil的处理范围内,单独处理任一程序集时均能正常解析。
尝试的临时解决方案
方案1:硬编码程序集路径
添加以下代码可临时解决问题,但不具备通用性:
if (baseType == null) { var test = AssemblyDefinition.ReadAssembly("<硬编码的程序集绝对路径>"); baseType = test.MainModule.GetType(asmType.BaseType.FullName); }
方案2:通过Module.FileName读取程序集失败
尝试通过asmType.BaseType.Module.FileName获取基类程序集路径并读取,但发现FileName返回的是派生类asmType所在程序集的文件名,而非基类的,导致方案失效:
AssemblyDefinition.ReadAssembly(asmType.BaseType.Module.FileName)
最终解决方案
通过自定义AssemblyDefinition缓存(仅存储非null的解析结果)解决了问题。
原因在于Mono.Cecil的DefaultAssemblyResolver存在缓存逻辑:当首次解析程序集失败时,会将null值存入缓存。即便后续该程序集能够被成功解析,Resolve方法也会直接返回缓存中的null,导致无法正确解析基类。自定义缓存仅保留有效解析结果,避免了这个问题。
内容的提问来源于stack exchange,提问作者Dave Doknjas
相关产品推荐
相关产品推荐

