如何编写使用某些库的不同版本的代码,这些库无需任何代码更改即可编译

本文关键字:代码 编译 任何 版本 何编写 | 更新日期: 2023-09-27 18:10:16

我希望能够编写一个使用库代码的函数(让它称为libx),而不必根据我使用的libx版本更改代码。

例如

public string ReturnFormattedString(string input) {
    //If using version 1 of library
    return libx.SomeClass.FormatString(input);
    //If using version 1 of library
    //If using version 2 of library
    return libx.SomeNewClass.FormatString(intput); 
    //Note: libx.SomeNewClass is not available in version 1
    //If using version 2 of library
}

我甚至不确定这是否可能,但我想知道这样的事情是如何实现的,这样我就可以编译我的代码,而不必根据使用的libx版本做任何更改。

编辑:

只是为了澄清一些事情。我没有访问libx的代码。我的应用程序是一个插件,在使用libx的另一个程序的顶部工作。所以libx的版本取决于我插入的程序的版本。

我开始认为,如果没有两个不同的程序集,每个程序集都有不同的ReturnFormattedString实现,这可能是不可能的,根据我所针对的libx版本(这是我首先要避免的)。

如何编写使用某些库的不同版本的代码,这些库无需任何代码更改即可编译

在这种情况下,您将返回一个字符串,因此即使代码更改,调用者也无法看到实现更改。但是,通常您可以使用基于接口的编程:

public string ReturnFormattedString(string input, iSomeClass myInjectedClass) {
    //If using version 1 of library
    return libx.myInjectedClass.FormatString(input);
    //If using version 1 of library
    //If using version 2 of library
    return libx.myInjectedClass.FormatString(intput); 
    //Note: libx.SomeNewClass is not available in version 1
    //If using version 2 of library
}

现在调用者通过依赖注入来定义实现。

结合良好的OO设计,您将拥有实现开闭原则的可维护代码的最佳可能性。

当然,实际上,范围蔓延和/或需求变化最终可能导致破坏合同的更改。生活就是这样。

作为一个项目需要一个硬依赖,我不建议一个项目支持,除非你添加每个DLL作为参考。

你当然可以用先进的设计模式来抵消成本和复杂性,比如@P.Brian。麦基提到的,比如依赖注入。我支持使用设计模式来解决代码的复杂性。但是,如果要处理两个类,这可能会很麻烦,因此这里的作用域很重要。或者您的大部分代码可以是一个中心库(可能是也可能不是一个PCL),并且只有变体在子项目中,每个版本对应一个您需要的版本。

也可以做你所要求的,每个版本使用一个单独的项目,使用自定义条件符号。在VS项目设置>构建选项卡中,有一个条件编译符号文本框,无论你把它放在那里你都可以做:

#if VERSION1
#else
#endif

并使用它来根据目标框架改变逻辑(参见更多信息)。你所要做的就是改变符号,或者把代码放在一个文件夹里,然后有多个项目文件指向相同的代码,每个都有自己的编译符号。这可能很乏味,因为您必须不断地映射文件,但是您可以使用Project Linker之类的工具来管理它。