条件编译和框架目标

条件编译和框架目标

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

类似于:

#if NET40using FooXX = Foo40;#elif NET35using FooXX = Foo35;#else NET20using FooXX = Foo20;#endif

这些符号中有免费的吗?是否需要将这些符号作为项目配置的一部分注入?似乎很容易做到,因为我将知道哪个框架是针对MSBuild的。

/p:DefineConstants="NET40"

最新情况:我的问题是,人们是如何处理这种情况的?您正在创建不同的配置吗?您是否通过命令行传入常量?


小唯快跑啊
浏览 556回答 3
3回答

偶然的你

实现这一目标的最佳方法之一是在项目中创建不同的构建配置:<PropertyGroup&nbsp;Condition="&nbsp;&nbsp;'$(Framework)'&nbsp;==&nbsp;'NET20'&nbsp;"> &nbsp;&nbsp;<DefineConstants>NET20</DefineConstants> &nbsp;&nbsp;<OutputPath>bin\$(Configuration)\$(Framework)</OutputPath></PropertyGroup><PropertyGroup&nbsp;Condition="&nbsp;&nbsp;'$(Framework)'&nbsp;==&nbsp;'NET35'&nbsp;"> &nbsp;&nbsp;<DefineConstants>NET35</DefineConstants> &nbsp;&nbsp;<OutputPath>bin\$(Configuration)\$(Framework)</OutputPath></PropertyGroup>在您的默认配置中:<Framework&nbsp;Condition="&nbsp;'$(Framework)'&nbsp;==&nbsp;''&nbsp;">NET35</Framework>这将设置默认的,如果它不是在其他地方定义的。在上述情况下,每次生成每个版本时,OutputPath都会为您提供一个单独的程序集。然后创建一个AfterBuild目标来编译您的不同版本:<Target&nbsp;Name="AfterBuild"> &nbsp;&nbsp;<MSBuild&nbsp;Condition="&nbsp;'$(Framework)'&nbsp;!=&nbsp;'NET20'" &nbsp;&nbsp;&nbsp;&nbsp;Projects="$(MSBuildProjectFile)" &nbsp;&nbsp;&nbsp;&nbsp;Properties="Framework=NET20" &nbsp;&nbsp;&nbsp;&nbsp;RunEachTargetSeparately="true"&nbsp;&nbsp;/></Target>此示例将在第一次构建后将Framework变量设置为NET 20重新编译整个项目(编译两者,并假设第一个构建是上面所述的默认NET 35)。每个编译都将正确设置条件定义值。通过这种方式,您甚至可以将项目文件中的某些文件排除在外,如果您希望w/o必须使用#ifdef文件:<Compile&nbsp;Include="SomeNet20SpecificClass.cs"&nbsp;Condition="&nbsp;'$(Framework)'&nbsp;==&nbsp;'NET20'&nbsp;"&nbsp;/>甚至是参考资料<Reference&nbsp;Include="Some.Assembly"&nbsp;Condition=""&nbsp;'$(Framework)'&nbsp;==&nbsp;'NET20'&nbsp;"&nbsp;> &nbsp;&nbsp;<HintPath>..\Lib\$(Framework)\Some.Assembly.dll</HintPath></Reference>

慕沐林林

到目前为止,我使用的另一种方法是将以下内容添加到项目文件中:&nbsp;<PropertyGroup> &nbsp;&nbsp;&nbsp;&nbsp;<DefineConstants&nbsp;Condition="&nbsp;!$(DefineConstants.Contains(';NET'))&nbsp;">$(DefineConstants);$(TargetFrameworkVersion.Replace("v",&nbsp;"NET").Replace(".",&nbsp;""))</DefineConstants> &nbsp;&nbsp;&nbsp;&nbsp;<DefineConstants&nbsp;Condition="&nbsp;$(DefineConstants.Contains(';NET'))&nbsp;">$(DefineConstants.Remove($(DefineConstants.LastIndexOf(";NET"))));$(TargetFrameworkVersion.Replace("v",&nbsp;"NET").Replace(".",&nbsp;""))</DefineConstants> &nbsp;&nbsp;</PropertyGroup>这使用TargetFrameworkVersion属性的值,它类似于“v3.5”,替换了“v”和“。获得“NET 35”(使用新的属性函数特征)。然后删除任何现有的“NETxx”值,并将其添加到DefinedConstants的末尾。这也许是可能的精简,但我没有时间去小提琴。在VS中查看项目属性的Build选项卡,您将在条件编译符号部分看到结果值。更改应用程序选项卡上的目标框架版本,然后自动更改符号。然后你可以用#if NETxx预处理指令以通常的方式。在VS中更改项目似乎不会丢失自定义PropertyGroup。请注意,这并没有为客户端配置文件目标选项提供任何不同的选项,但这对我来说不是一个问题。

慕后森

我对这些解有问题,可能是因为我的初始常数是由这些属性预先建立的。<DefineConstants&nbsp;/><DefineDebug>true</DefineDebug><DefineTrace>true</DefineTrace><DebugSymbols>true</DebugSymbols>VisualStudio 2010还因为分号而抛出一个错误,声称它们是非法字符。错误消息给了我一个提示,因为我可以看到预先构建的常量由逗号分隔,最后是我的“非法”分号。经过一些调整和按摩后,我想出了一个适合我的解决方案。<PropertyGroup> &nbsp;&nbsp;<!--&nbsp;Adding&nbsp;a&nbsp;custom&nbsp;constant&nbsp;will&nbsp;auto-magically&nbsp;append&nbsp;a&nbsp;comma&nbsp;and&nbsp;space&nbsp;to&nbsp;the&nbsp;pre-built&nbsp;constants.&nbsp;&nbsp;&nbsp;&nbsp;--> &nbsp;&nbsp;<!--&nbsp;Move&nbsp;the&nbsp;comma&nbsp;delimiter&nbsp;to&nbsp;the&nbsp;end&nbsp;of&nbsp;each&nbsp;constant&nbsp;and&nbsp;remove&nbsp;the&nbsp;trailing&nbsp;comma&nbsp;when&nbsp;we're&nbsp;done.&nbsp;&nbsp;--> &nbsp;&nbsp;<DefineConstants&nbsp;Condition="&nbsp;!$(DefineConstants.Contains(',&nbsp;NET'))&nbsp;">$(DefineConstants)$(TargetFrameworkVersion.Replace("v",&nbsp;"NET").Replace(".",&nbsp;"")),&nbsp;</DefineConstants> &nbsp;&nbsp;<DefineConstants&nbsp;Condition="&nbsp;$(DefineConstants.Contains(',&nbsp;NET'))&nbsp;">$(DefineConstants.Remove($(DefineConstants.LastIndexOf(",&nbsp;NET"))))$(TargetFrameworkVersion.Replace("v",&nbsp;"NET").Replace(".",&nbsp;"")),&nbsp;</DefineConstants> &nbsp;&nbsp;<DefineConstants&nbsp;Condition="&nbsp;$(TargetFrameworkVersion.Replace('v',&nbsp;''))&nbsp;>=&nbsp;2.0&nbsp;">$(DefineConstants)NET_20_OR_GREATER,&nbsp;</DefineConstants> &nbsp;&nbsp;<DefineConstants&nbsp;Condition="&nbsp;$(TargetFrameworkVersion.Replace('v',&nbsp;''))&nbsp;>=&nbsp;3.5&nbsp;">$(DefineConstants)NET_35_OR_GREATER</DefineConstants> &nbsp;&nbsp;<DefineConstants&nbsp;Condition="&nbsp;$(DefineConstants.EndsWith(',&nbsp;'))&nbsp;">$(DefineConstants.Remove($(DefineConstants.LastIndexOf(",&nbsp;"))))</DefineConstants></PropertyGroup>我会发布高级编译器设置对话框的屏幕截图(单击“高级编译选项.”打开)。按钮在项目的“编译”选项卡上)。但作为一个新用户,我缺乏这样做的代表。如果你能看到截图,你会看到自定义常量自动填充的属性组,然后你会说,“我要给我一些。”
打开App,查看更多内容
随时随地看视频慕课网APP