如果目标框架是较新的版本,则在一些较小的地方可以极大地改进我的项目代码。我希望能够更好地利用C#中的条件编译来根据需要切换这些条件。
就像是:
#if NET40 using FooXX = Foo40; #elif NET35 using FooXX = Foo35; #else NET20 using FooXX = Foo20; #endif
这些符号中的任何一个免费吗?我是否需要在项目配置中注入这些符号?这样做似乎很容易,因为我将了解MSBuild所针对的框架。
/p:DefineConstants="NET40"
人们如何处理这种情况?您要创建其他配置吗?您是否通过命令行传递常量?
最好的方法之一是在项目中创建不同的构建配置:
<PropertyGroup Condition=" '$(Framework)' == 'NET20' "> <DefineConstants>NET20</DefineConstants> <OutputPath>bin\$(Configuration)\$(Framework)</OutputPath> </PropertyGroup> <PropertyGroup Condition=" '$(Framework)' == 'NET35' "> <DefineConstants>NET35</DefineConstants> <OutputPath>bin\$(Configuration)\$(Framework)</OutputPath> </PropertyGroup>
在您的默认配置之一中:
<Framework Condition=" '$(Framework)' == '' ">NET35</Framework>
如果未在其他任何地方定义默认值,它将设置默认值。在上述情况下,每次构建每个版本时,OutputPath都会为您提供一个单独的程序集。
然后创建一个AfterBuild目标以编译您的不同版本:
<Target Name="AfterBuild"> <MSBuild Condition=" '$(Framework)' != 'NET20'" Projects="$(MSBuildProjectFile)" Properties="Framework=NET20" RunEachTargetSeparately="true" /> </Target>
此示例将在第一次构建后将Framework变量设置为NET20的情况下重新编译整个项目(同时编译并假定第一次构建是上述默认的NET35)。每个编译将具有正确设置的条件定义值。
通过这种方式,如果您希望不必#ifdef这些文件,甚至可以排除项目文件中的某些文件:
<Compile Include="SomeNet20SpecificClass.cs" Condition=" '$(Framework)' == 'NET20' " />
甚至参考
<Reference Include="Some.Assembly" Condition="" '$(Framework)' == 'NET20' " > <HintPath>..\Lib\$(Framework)\Some.Assembly.dll</HintPath> </Reference>