2017-05-26 26 views
1

.NET标准的承诺是为一个版本编写的任何内容都适用于将来的版本。有条件编译.NET的最低版本

现在我可以有条件地编译东西,例如

#if NETSTANDARD1_3 
// do things 
#elif NETSTANDARD1_4 || NETSTANDARD2_0 || NET45 
// do other things 
#endif 

但对我来说,这似乎具有很差的可扩展性,因为如果我决定在未来添加新的目标,例如,对于.NET Standard 2.1,我必须在有这些条件的地方去更新它。

我希望做的是一样的东西:

#if NETSTANDARD1_3 
// do things 
#elif NETSTANDARD1_4_OR_GREATER || NET45_OR_GREATER 
// do other things 
#endif 

我目前的解决方案是创建这些_OR_GREATER手动定义在我的项目文件。这至少使我的维护到一个单一的文件,而不是每个源文件:

<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> 
    <DefineConstants>NETSTANDARD1_4_OR_GREATER;$(DefineConstants)</DefineConstants> 
</PropertyGroup> 

不过,我很好奇,如果这已经占到了其他一些更标准的方式。这是一件事吗?

+0

谁downvoted的问题,头脑解释为什么? –

+0

我认为这个问题是有效的,但可能需要一些改写,说明意图 - 最低版本的DefineConstant。 –

+0

(哦,这不是我,我upvoted,因为我觉得这非常有用) –

回答

3

这是可能的几个msbuild技巧。 SDK目标(隐式导入项目SDK="…"属性<Project/>)将TargetFramework属性拆分为TargetFrameworkIdentifierTargetFrameworkVersion

所以<TargetFramework>netstandard1.5</…>会导致:

  • $(TargetFrameworkIdentifier).NETStandard
  • $(TargetFrameworkVersion)v1.5
  • $(_ TargetFrameworkVersionWithoutV)1.5,但这个属性是按照惯例(下划线) “私人”,并且不应因为它可能会改变/不保证可以被自定义目标使用。

比较字符串时,MSBuild试图在比较之前将它们解析为版本,因此我们可以比较'1.5' >= '1.4'。使用这种 ,我们可以挂钩一个目标的编译过程之前设置基于版本范围自定义变量:

<Target Name="AddNetStdMinDefine" 
     BeforeTargets="CoreCompile" 
     Condition="('$(TargetFrameworkIdentifier)' == '.NETStandard' and '$(TargetFrameworkVersion.Substring(1))' &gt;= '1.4')"> 
    <PropertyGroup> 
    <DefineConstants>$(DefineConstants);IS_MIN_NETSTANDARD1_4</DefineConstants> 
    </PropertyGroup> 
</Target>