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 8 | 8 | net8.0 | 2.1 |
.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.1 | net481 | 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* net8.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 net481 |
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
和 net8.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-tizen | tizen40 (以及从 net7.0 继承的所有其他内容) |
net7.0-tvos | (后续版本的 net6.0-tvos ) |
net7.0-windows | (后续版本的 net6.0-windows ) |
net8.0 | (后续版本的 net7.0 ) |
net8.0-android | (后续版本的 net7.0-android ) |
net8.0-browser | 从 net8.0 继承的所有内容 |
net8.0-ios | (后续版本的 net7.0-ios ) |
net8.0-maccatalyst | (后续版本的 net7.0-maccatalyst ) |
net8.0-macos | (后续版本的 net7.0-macos ) |
net8.0-tizen | (后续版本的 net7.0-tizen ) |
net8.0-tvos | (后续版本的 net7.0-tvos ) |
net8.0-windows | (后续版本的 net7.0-windows ) |
若要使应用可跨不同平台移植,但仍有权访问特定于 OS 的 API,你可以定位多个特定于 OS 的 TFM,并使用 #if
预处理器指令围绕特定于 OS 的 API 调用增加平台防护。 有关可用符号的列表,请参阅预处理器符号。
建议的目标
使用以下准则确定在应用中使用哪种 TFM:
可移植到多个平台的应用应面向基础 TFM,例如
net8.0
。 这包括大多数库,但也包含 ASP.NET Core 和实体框架。特定于平台的库应面向特定于平台的风格。 例如,WinForms 和 WPF 项目应面向
net8.0-windows
。跨平台应用模型(Xamarin Forms、ASP.NET Core)和网桥包 (Xamarin Essentials) 应至少面向基础 TFM(例如
net8.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 版本的默认目标平台 (TPV)。
.NET 版本 | 平台 | 默认 TPV |
---|---|---|
.NET 6 | Android | 31.0 |
.NET 7 | Android | 33.0 |
.NET 8 | Android | 34.0 |
.NET 6 | iOS | 15.0 |
.NET 7 | iOS | 16.1 |
.NET 8 | iOS | 17.2 |
.NET 6 | Mac Catalyst | 15.0 |
.NET 7 | Mac Catalyst | 16.1 |
.NET 8 | Mac Catalyst | 17.2 |
.NET 6 | macOS | 12.0 |
.NET 7 | macOS | 13.0 |
.NET 8 | macOS | 14.2 |
.NET 6 | tvOS | 15.1 |
.NET 7 | tvOS | 16.1 |
.NET 8 | tvOS | 17.1 |
.NET 7 | Tizen | 7.0 |
.NET 8 | Tizen | 8.0 |
.NET 6 | Windows | 7.0 |
.NET 7 | Windows | 7.0 |
.NET 8 | Windows | 7.0 |
.NET SDK 设计为能够支持单个平台的新发布的 API,而无需使用新版本的基础 TFM。 这样,你无需等待 .NET 的主要版本就能访问特定于平台的功能。 可以通过在 TFM 中增加平台版本来访问这些新发布的 API。 例如,如果 iOS 平台在 .NET 6.0.x SDK 更新中添加了 iOS 15.1 API,你可以使用 TFM net6.0-ios15.1
访问它们。
优先顺序
如果应用引用了一个包,该包具有不同 TFM 的多个资产,则首选版本号更接近的资产。 例如,如果应用面向 net6.0-ios
并且包提供 net6.0
和 net5.0-ios
资产,则使用 net6.0
资产。 有关详细信息,请参阅优先顺序。
支持旧版 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 8:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.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 、NET8_0 、NET7_0 、NET6_0 、NET5_0 、NETCOREAPP 、NETCOREAPP3_1 、NETCOREAPP3_0 、NETCOREAPP2_2 、NETCOREAPP2_1 、NETCOREAPP2_0 、NETCOREAPP1_1 、NETCOREAPP1_0 |
NET8_0_OR_GREATER , 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 、BROWSER 、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
。 NETSTANDARD<x>_<y>_OR_GREATER
符号仅针对 .NET Standard 目标定义,而不适用于实现 .NET Standard 的目标,例如 .NET Core 和 .NET Framework。- 它们与 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 |