我有一些改进目前给出的答案的建议:
-
使用 Version.CompareTo()。相等性测试不适用于更高版本的框架,尚未命名。例如
<CustomConstants Condition=" '$(TargetFrameworkVersion)' == 'v4.0' ">
不会匹配 v4.5 或 v4.5.1,这通常是您想要的。
使用导入文件,这样这些附加属性只需定义一次。我建议将导入文件置于源代码控制之下,以便更改与项目文件一起传播,而无需额外的努力。
在项目文件的末尾添加导入元素,使其独立于任何配置特定的属性组。这还有一个好处是需要在项目文件中增加一行。
这里是导入文件(VersionSpecificSymbols.Common.prop)
<!--
******************************************************************
Defines the Compile time symbols Microsoft forgot
Modelled from https://msdn.microsoft.com/en-us/library/ms171464.aspx
*********************************************************************
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.5.1')))) >= 0">$(DefineConstants);NETFX_451</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.5')))) >= 0">$(DefineConstants);NETFX_45</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.0')))) >= 0">$(DefineConstants);NETFX_40</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('3.5')))) >= 0">$(DefineConstants);NETFX_35</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('3.0')))) >= 0">$(DefineConstants);NETFX_30</DefineConstants>
</PropertyGroup>
</Project>
将导入元素添加到项目文件
在您的 .csproj 文件中添加引用它,方法是在标记之前添加。
…
<Import Project="VersionSpecificSymbols.Common.prop" />
</Project>
您需要修复指向您放置此文件的公共/共享文件夹的路径。
使用编译时符号
namespace VersionSpecificCodeHowTo
{
using System;
internal class Program
{
private static void Main(string[] args)
{
#if NETFX_451
Console.WriteLine("NET_451 was set");
#endif
#if NETFX_45
Console.WriteLine("NET_45 was set");
#endif
#if NETFX_40
Console.WriteLine("NET_40 was set");
#endif
#if NETFX_35
Console.WriteLine("NETFX_35 was set");
#endif
#if NETFX_30
Console.WriteLine("NETFX_30 was set");
#endif
#if NETFX_20
Console.WriteLine("NETFX_20 was set");
#else
The Version specific symbols were not set correctly!
#endif
#if DEBUG
Console.WriteLine("DEBUG was set");
#endif
#if MySymbol
Console.WriteLine("MySymbol was set");
#endif
Console.ReadKey();
}
}
}
一个常见的“现实生活”示例
在 .NET 4.0 之前实现 Join(字符串分隔符,IEnumerable 字符串)
// string Join(this IEnumerable<string> strings, string delimiter)
// was not introduced until 4.0. So provide our own.
#if ! NETFX_40 && NETFX_35
public static string Join( string delimiter, IEnumerable<string> strings)
{
return string.Join(delimiter, strings.ToArray());
}
#endif
参考文献
Property Functions
MSBuild Property Evaluation
Can I make a preprocessor directive dependent on the .NET framework version?
Conditional compilation depending on the framework version in C#