有条件地编译最低版本的 .NET
Conditionally compiling for a minimum version of .NET
.NET Standard 的承诺是为一个版本编写的任何内容都适用于未来的版本。
现在我可以有条件地编译东西,例如
#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>
但是,我很好奇是否已经以其他一些更标准的方式解决了这个问题。这是一件事吗?
这可以通过一些 msbuild 技巧来实现。 SDK 目标(通过 <Project/>
上的 SDK="…"
属性隐式导入 after 项目)将 TargetFramework
属性 拆分为 TargetFrameworkIdentifier
和 TargetFrameworkVersion
.
所以<TargetFramework>netstandard1.5</…>
会导致:
$(TargetFrameworkIdentifier)
变为 .NETStandard
$(TargetFrameworkVersion)
变为 v1.5
$(_TargetFrameworkVersionWithoutV)
变为 1.5
,但是这个 属性 按照约定(下划线)是 "private",不应使用,因为它可能会更改/不会保证可由自定义目标使用。
比较字符串时,MSBuild 会尝试在比较之前将它们解析为版本,以便我们可以进行比较 '1.5' >= '1.4'
。
使用它,我们可以在编译过程之前挂钩目标以根据版本范围设置自定义变量:
<Target Name="AddNetStdMinDefine"
BeforeTargets="CoreCompile"
Condition="('$(TargetFrameworkIdentifier)' == '.NETStandard' and '$(TargetFrameworkVersion.Substring(1))' >= '1.4')">
<PropertyGroup>
<DefineConstants>$(DefineConstants);IS_MIN_NETSTANDARD1_4</DefineConstants>
</PropertyGroup>
</Target>
.NET Standard 的承诺是为一个版本编写的任何内容都适用于未来的版本。
现在我可以有条件地编译东西,例如
#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>
但是,我很好奇是否已经以其他一些更标准的方式解决了这个问题。这是一件事吗?
这可以通过一些 msbuild 技巧来实现。 SDK 目标(通过 <Project/>
上的 SDK="…"
属性隐式导入 after 项目)将 TargetFramework
属性 拆分为 TargetFrameworkIdentifier
和 TargetFrameworkVersion
.
所以<TargetFramework>netstandard1.5</…>
会导致:
$(TargetFrameworkIdentifier)
变为.NETStandard
$(TargetFrameworkVersion)
变为v1.5
$(_TargetFrameworkVersionWithoutV)
变为1.5
,但是这个 属性 按照约定(下划线)是 "private",不应使用,因为它可能会更改/不会保证可由自定义目标使用。
比较字符串时,MSBuild 会尝试在比较之前将它们解析为版本,以便我们可以进行比较 '1.5' >= '1.4'
。
使用它,我们可以在编译过程之前挂钩目标以根据版本范围设置自定义变量:
<Target Name="AddNetStdMinDefine"
BeforeTargets="CoreCompile"
Condition="('$(TargetFrameworkIdentifier)' == '.NETStandard' and '$(TargetFrameworkVersion.Substring(1))' >= '1.4')">
<PropertyGroup>
<DefineConstants>$(DefineConstants);IS_MIN_NETSTANDARD1_4</DefineConstants>
</PropertyGroup>
</Target>