c# - 条件编译和框架目标

标签 c# .net-3.5 msbuild .net-4.0

如果目标框架是较新的版本,我的项目的代码可能会在一些小地方得到显着改进。我希望能够更好地利用 C# 中的条件编译来根据需要切换它们。

类似于:

#if NET40
using FooXX = Foo40;
#elif NET35
using FooXX = Foo35;
#else NET20
using FooXX = Foo20;
#endif

这些符号中的任何一个都是免费的吗?我是否需要将这些符号作为项目配置的一部分注入(inject)?这似乎很容易做到,因为我会知道 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>

关于c# - 条件编译和框架目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30592756/

相关文章:

c# - 我的线程在就绪队列中吗?

c# - 在 WPF 中检测鼠标直接越过边框

msbuild - 如何在调用之前检查目标是否存在?

visual-studio-2010 - MS Build 未在构建服务器上编译 MS 测试项目

c# - 正则表达式匹配带有 +(加号)的单词

c# - 验证 Google OpenID Connect JWT ID token

c# - 如何将自定义类型与 WCF 数据服务和 EF 一起使用

wpf - 如何在 WPF 中的模板化 TabItem 上获得关闭按钮?

visual-studio-2008 - 如果 DLL 的 app.config 应该在 "main config"中……我们如何处理 DLL 中的 WCF 引用?

c# - 如何从 MSBuild 代码分析中获取 XML 报告