C#如何基于外部DLL版本实现条件编译以兼容低版本API?
解决方案
你当前的代码中运行时版本判断逻辑在编译环节之后才会执行,编译器在编译阶段会强校验引用的外部DLL类型是否包含调用的方法,低版本DLL不存在GetUnsortedFaces()方法时自然会触发编译报错,和运行时的逻辑无关。
下面给出两种可行方案:
方案1:反射调用(兼容高低版本DLL的同一份编译产物)
直接通过反射调用高版本特有的方法,编译阶段不会做方法存在性校验,同时保留运行时的版本判断逻辑:
List<IVctFace> IVctEdge.AllFaces() { Face[] faces; Version version = System.Reflection.Assembly.GetAssembly(typeof(Edge)).GetName().Version; faces = this.Edge.GetFaces(); if (version.Major > 11) { // 反射获取高版本新增的GetUnsortedFaces方法 var getUnsortedFacesMethod = typeof(Edge).GetMethod("GetUnsortedFaces", Type.EmptyTypes); if (getUnsortedFacesMethod != null) { faces = (Face[])getUnsortedFacesMethod.Invoke(this.Edge, null); } } List<IVctFace> vctFaces = new List<IVctFace>(); foreach (Face face in faces) { vctFaces.Add(new VctFace(face, this.Parent.Parent)); } return vctFaces; }
如果担心反射调用的性能损耗,可以将GetUnsortedFaces的MethodInfo缓存为静态字段,避免每次调用都重复反射查找。
方案2:条件编译符号(适合针对不同DLL版本分别编译的场景)
如果你可以接受针对不同DLL版本分别打包程序集,可以不用在代码里写#define,直接在项目配置中定义条件编译常量:
- 右键项目 -> 属性 -> 生成 -> 常规 -> 条件编译符号,输入
USE_V12_API - 用预处理指令包裹高版本特有代码:
if (version.Major > 11) { #if USE_V12_API faces = this.Edge.GetUnsortedFaces(); #endif }
切换引用的DLL版本时,只需要修改项目配置中的条件编译符号即可,不需要改动业务代码。
内容的提问来源于stack exchange,提问作者Sahil Verma
相关产品推荐
相关产品推荐

