SDK 样式项目中的目标框架
以应用或库中的框架为目标时,需要指定想要向应用或库提供的 API 集。 使用目标框架名字对象 (TFM) 在项目文件中指定目标框架。
应用或库可以使用 .NET Standard 版本作为目标。 .NET Standard 版本表示所有 .NET 实现中的标准化 API 集。 例如,库可以使用 .NET Standard 1.6 作为目标,并获得对可使用相同基本代码跨 .NET Core 和 .NET Framework 工作的 API 的访问权限。
应用或库还能以一个特定 .NET 实现为目标,获得特定于实现的 API 的访问权限。 例如,面向 Xamarin.iOS 的应用(如 Xamarin.iOS10
)有权访问 Xamarin 提供的适用于 iOS 10 的 iOS API 包装器;面向通用 Windows 平台 (UWP) 的应用(如 uap10.0
)有权访问为运行 Windows 10 的设备编译的 API。
对于某些目标框架(例如 .NET Framework),API 由框架在系统上安装的程序集定义,并且可能包括应用程序框架 API(例如 ASP.NET)。
对于基于包的目标框架(例如 .NET 5+、.NET Core 和 .NET Standard),API 是由应用或库中包含的 NuGet 包定义的。
最新版本
下表定义了最常见的目标框架、如何引用这些框架,以及它们实现的 .NET Standard 版本。 这些目标框架版本是最新的稳定版本。 预发行版不会显示。 目标框架名字对象 (TFM) 是一个标准化令牌格式,用于指定 .NET 应用或库的目标框架。
目标框架 | 最新 稳定版本 |
目标框架名字对象 (TFM) | 已实现 .NET Standard 版本 |
---|---|---|---|
.NET 7 | 7 | net7.0 | 2.1 |
.NET 6 | 6 | net6.0 | 2.1 |
.NET 5 | 5 | net5.0 | 2.1 |
.NET Standard | 2.1 | netstandard2.1 | 空值 |
.NET Core | 3.1 | netcoreapp3.1 | 2.1 |
.NET Framework | 4.8 | net48 | 2.0 |
支持的目标框架
目标框架通常由 TFM 引用。 下表显示 .NET SDK 和 NuGet 客户端支持的目标框架。 等效项显示在括号内。 例如,win81
对于 netcore451
来说等效于 TFM。
目标 Framework | TFM |
---|---|
.NET 5 及更高版本(和 .NET Core) | netcoreapp1.0 netcoreapp1.1 netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 net5.0* net6.0* net7.0* |
.NET Standard | netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 netstandard2.1 |
.NET Framework | net11 net20 net35 net40 net403 net45 net451 net452 net46 net461 net462 net47 net471 net472 net48 |
Windows 应用商店 | netcore [netcore45] netcore45 [win] [win8] netcore451 [win81] |
.NET Micro Framework | netmf |
Silverlight | sl4 sl5 |
Windows Phone | wp [wp7] wp7 wp75 wp8 wp81 wpa81 |
通用 Windows 平台 | uap [uap10.0] uap10.0 [win10] [netcore50] |
* .NET 5 及更高版本的 TFM 包含一些特定于操作系统的变体。 有关详细信息,请参阅下一节:.NET 5 及更高版本特定于 OS 的 TFM。
.NET 5 及更高版本特定于 OS 的 TFM
net5.0
、net6.0
和 net7.0
TFM 包括可在不同平台中使用的技术。 指定特定于 OS 的 TFM 使特定于操作系统的 API 可供你的应用(例如 Windows 窗体或 iOS 绑定)使用。 特定于 OS 的 TFM 还会继承其基础 TFM(例如 net6.0
TFM)可用的每个 API。
.NET 5 引入了 net5.0-windows
特定于 OS 的 TFM,其中包括适用于 WinForms、WPF 和 UWP API 的特定于 Windows 的绑定。 .NET 6 及更高版本具有其他特定于 OS 的 TPM,例如 net6.0-ios
。
下表说明了 .NET 5 及更高版本 TFM 的兼容性。
TFM | 可兼容对象 |
---|---|
net5.0 | net1..4(带有 NU1701 警告) netcoreapp1..3.1 (引用 WinForms 或 WPF 时出现警告) netstandard1..2.1 |
net5.0-windows | netcoreapp1..3.1(以及从 net5.0 继承的所有其他内容) |
net6.0 | (后续版本的 net5.0 ) |
net6.0-android | xamarin.android (以及从 net6.0 继承的所有其他内容) |
net6.0-ios | xamarin.ios (以及从 net6.0 继承的所有其他内容) |
net6.0-maccatalyst | xamarin.ios (以及从 net6.0 继承的所有其他内容) |
net6.0-macos | xamarin.mac (以及从 net6.0 继承的所有其他内容) |
net6.0-tvos | xamarin.tvos (以及从 net6.0 继承的所有其他内容) |
net6.0-windows | (后续版本的 net5.0-windows ) |
net7.0 | (后续版本的 net6.0 ) |
net7.0-android | (后续版本的 net6.0-android ) |
net7.0-ios | (后续版本的 net6.0-ios ) |
net7.0-maccatalyst | (后续版本的 net6.0-maccatalyst ) |
net7.0-macos | (后续版本的 net6.0-macos ) |
net7.0-tvos | (后续版本的 net6.0-tvos ) |
net7.0-windows | (后续版本的 net6.0-windows ) |
若要使应用可跨不同平台移植,但仍有权访问特定于 OS 的 API,你可以定位多个特定于 OS 的 TFM,并使用 #if
预处理器指令围绕特定于 OS 的 API 调用增加平台防护。 有关可用符号的列表,请参阅预处理器符号。
建议的目标
使用以下准则确定在应用中使用哪种 TFM:
可移植到多个平台的应用应面向基础 TFM,例如
net6.0
。 这包括大多数库,但也包含 ASP.NET Core 和实体框架。特定于平台的库应面向特定于平台的风格。 例如,WinForms 和 WPF 项目应面向
net6.0-windows
。跨平台应用模型(Xamarin Forms、ASP.NET Core)和网桥包 (Xamarin Essentials) 应至少面向基础 TFM(例如
net6.0
),但也可以面向其他特定于平台的风格来支持更多的 API 或功能。
TFM 中的 OS 版本
你还可以在 OS 特定的 TFM 的末尾指定可选的 OS 版本,例如,net6.0-ios15.0
。 版本指示应用或库可用的 API。 它不控制应用或库在运行时支持的 OS 版本。 它用于选择项目编译的引用程序集,并用于从 NuGet 包中选择资产。 将此版本视为“平台版本”或“OS API 版本”,可以与运行时 OS 版本进行区分。
当特定于 OS 的 TFM 不显式指定平台版本时,它具有可从基础 TFM 和平台名称推断的隐含值。 例如,.NET 6 中 iOS 的默认平台值为 15.0
,这意味着 net6.0-ios
是规范 net6.0-ios15.0
TFM 的简写形式。 较新的基础 TFM 的隐含平台版本可能更高,例如,将来的 net8.0-ios
TFM 可以映射到 net8.0-ios16.0
。 简写形式仅用于项目文件,在传递给其他工具(如 NuGet)之前,.NET SDK 的 MSBuild 目标将其扩展为规范格式。
.NET SDK 设计为能够支持单个平台的新发布的 API,而无需使用新版本的基础 TFM。 这样,你无需等待 .NET 的主要版本就能访问特定于平台的功能。 可以通过在 TFM 中增加平台版本来访问这些新发布的 API。 例如,如果 iOS 平台在 .NET 6.0.x SDK 更新中添加了 iOS 15.1 API,你可以使用 TFM net6.0-ios15.1
访问它们。
支持旧版 OS
虽然特定于平台的应用或库是针对特定版本的 OS 中的 API 编译的,但你可以通过将 SupportedOSPlatformVersion
属性添加到项目文件,使其与早期版本的 OS 兼容。 SupportedOSPlatformVersion
属性指示运行应用或库所需的最低 OS 版本。 如果不在项目中显式指定此最低运行时 OS 版本,则默认为 TFM 中的平台版本。
若要使应用在较旧的 OS 版本上正常运行,它不能调用该 OS 版本上不存在的 API。 但是,可以增加对较新 API 的调用的防护,以便只有在支持这些 API 的 OS 版本上运行时,才能调用它们。 使用此模式可以设计应用或库,以支持在较旧的 OS 版本上运行,同时在较新的 OS 版本上运行时利用较新的 OS 功能。
SupportedOSPlatformVersion
值(无论是显式还是默认)由平台兼容性分析器使用,用于检测并警告对较新 API 的无防御调用。 它作为 UnsupportedOSPlatformAttribute 程序集属性记录到项目的编译程序集中,使平台兼容性分析器可以从具有较低值 SupportedOSPlatformVersion
的项目中检测对该程序集 API 的无防御调用。 在一些平台上,SupportedOSPlatformVersion
值会影响特定于平台的应用打包和生成过程,这些平台的文档对此有所介绍。
下面是一个项目文件的示例摘录,该文件使用 TargetFramework
和 SupportedOSPlatformVersion
MSBuild 属性指定应用或库有权访问 iOS 15.0 API,但支持在 iOS 13.0 及更高版本上运行:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-ios15.0</TargetFramework>
<SupportedOSPlatformVersion>13.0</SupportedOSPlatformVersion>
</PropertyGroup>
...
</Project>
如何指定目标框架
在项目文件中指定目标框架。 指定单个目标框架时,使用 TargetFramework 元素。 以下控制台应用项目文件演示了如何面向 .NET 6:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
指定多个目标框架时,可有条件地为每个目标框架引用程序集。 在代码中,可使用具有 if-then-else 逻辑的预处理器符号,有条件地针对这些程序集进行编译。
以下库项目面向 .NET Standard (netstandard1.4
) 和 .NET Framework(net40
和 net45
)的 API。 将复数形式的 TargetFrameworks 元素与多个目标框架一起使用。 为两个 .NET Framework TFM 编译库时,Condition
属性包括特定于实现的包:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.4;net40;net45</TargetFrameworks>
</PropertyGroup>
<!-- Conditionally obtain references for the .NET Framework 4.0 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">
<Reference Include="System.Net" />
</ItemGroup>
<!-- Conditionally obtain references for the .NET Framework 4.5 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System.Net.Http" />
<Reference Include="System.Threading.Tasks" />
</ItemGroup>
</Project>
在库或应用中,使用预处理器指令编写条件代码,针对每个目标框架进行编译:
public class MyClass
{
static void Main()
{
#if NET40
Console.WriteLine("Target framework: .NET Framework 4.0");
#elif NET45
Console.WriteLine("Target framework: .NET Framework 4.5");
#else
Console.WriteLine("Target framework: .NET Standard 1.4");
#endif
}
}
预处理器符号
使用 SDK 样式项目时,生成系统可识别预处理器符号,这些符号表示支持的目标框架版本表中所示的目标框架。 若要将 .NET Standard、.NET Core 或 .NET 5+ TFM 转换为预处理器符号,请将点和连字符替换为下划线,并将小写字母更改为大写字母(例如,netstandard1.4
的符号为 NETSTANDARD1_4
)。
可以通过 DisableImplicitFrameworkDefines
属性禁止生成这些符号。 有关此属性的详细信息,请参阅 DisableImplicitFrameworkDefines。
.NET 目标框架的预处理器符号的完整列表如下:
目标框架 | 符号 | 其他符号 (在 .NET 5+ SDK 中可用) |
平台符号(仅 在指定特定于 OS 的 TFM 时可用) |
---|---|---|---|
.NET Framework | NETFRAMEWORK , NET48 , NET472 , NET471 , NET47 , NET462 , NET461 , NET46 , NET452 , NET451 , NET45 , NET40 , NET35 , NET20 |
NET48_OR_GREATER , NET472_OR_GREATER , NET471_OR_GREATER , NET47_OR_GREATER , NET462_OR_GREATER , NET461_OR_GREATER , NET46_OR_GREATER , NET452_OR_GREATER , NET451_OR_GREATER , NET45_OR_GREATER , NET40_OR_GREATER , NET35_OR_GREATER , NET20_OR_GREATER |
|
.NET Standard | NETSTANDARD , NETSTANDARD2_1 , NETSTANDARD2_0 , NETSTANDARD1_6 , NETSTANDARD1_5 , NETSTANDARD1_4 , NETSTANDARD1_3 , NETSTANDARD1_2 , NETSTANDARD1_1 , NETSTANDARD1_0 |
NETSTANDARD2_1_OR_GREATER , NETSTANDARD2_0_OR_GREATER , NETSTANDARD1_6_OR_GREATER , NETSTANDARD1_5_OR_GREATER , NETSTANDARD1_4_OR_GREATER , NETSTANDARD1_3_OR_GREATER , NETSTANDARD1_2_OR_GREATER , NETSTANDARD1_1_OR_GREATER , NETSTANDARD1_0_OR_GREATER |
|
.NET 5 及更高版本(和 .NET Core) | NET , NET7_0 , NET6_0 , NET5_0 , NETCOREAPP , NETCOREAPP3_1 , NETCOREAPP3_0 , NETCOREAPP2_2 , NETCOREAPP2_1 , NETCOREAPP2_0 , NETCOREAPP1_1 , NETCOREAPP1_0 |
NET7_0_OR_GREATER , NET6_0_OR_GREATER , NET5_0_OR_GREATER , NETCOREAPP3_1_OR_GREATER , NETCOREAPP3_0_OR_GREATER , NETCOREAPP2_2_OR_GREATER , NETCOREAPP2_1_OR_GREATER , NETCOREAPP2_0_OR_GREATER , NETCOREAPP1_1_OR_GREATER , NETCOREAPP1_0_OR_GREATER |
ANDROID , IOS , MACCATALYST , MACOS , TVOS , WINDOWS ,[OS][version] (例如,IOS15_1 ),[OS][version]_OR_GREATER (例如,IOS15_1_OR_GREATER ) |
注意
- 无论目标版本是什么,都将定义无版本符号。
- 仅针对目标版本定义特定于版本的符号。
- 为目标版本和所有早期版本定义
<framework>_OR_GREATER
符号。 例如,如果针对 .NET Framework 2.0,则会定义以下符号:NET20
、NET20_OR_GREATER
、NET11_OR_GREATER
和NET10_OR_GREATER
。 - 它们与 MSBuild
TargetFramework
属性和 NuGet 使用的目标框架名字对象 (TFM) 不同。
已弃用的目标框架
以下目标框架已弃用。 面向这些目标框架的包应迁移到指定的替代框架。
已弃用的 TFM | Replacement |
---|---|
aspnet50 aspnetcore50 dnxcore50 dnx dnx45 dnx451 dnx452 |
netcoreapp |
dotnet dotnet50 dotnet51 dotnet52 dotnet53 dotnet54 dotnet55 dotnet56 |
netstandard |
netcore50 | uap10.0 |
win | netcore45 |
win8 | netcore45 |
win81 | netcore451 |
win10 | uap10.0 |
winrt | netcore45 |