Estruturas de destino em projetos no estilo SDK

Ao destinar a uma estrutura em um aplicativo ou uma biblioteca, você está especificando o conjunto de APIs que deseja disponibilizar para o aplicativo ou a biblioteca. Você especifica a estrutura de destino em seu arquivo de projeto usando o TFM (Moniker da Estrutura de Destino).

Um aplicativo ou uma biblioteca pode ser destinada a uma versão do .NET Standard. As versões do .NET Standard representam conjuntos de APIs padronizadas entre todas as implementações do .NET. Por exemplo, uma biblioteca pode se destinar ao NET Standard 1.6 e obter acesso a APIs que funcionam no .NET Core e .NET Framework usando a mesma base de código.

Um aplicativo ou uma biblioteca também pode se destinar a uma implementação específica do .NET para obter acesso a APIs específicas de implementação. Por exemplo, um aplicativo que tem como destino o Xamarin.iOS (por exemplo, Xamarin.iOS10) tem acesso aos wrappers da API fornecidos para Xamarin iOS do iOS 10 ou um aplicativo que tem como destino a UWP (Plataforma Universal do Windows, uap10.0) tem acesso a APIs que são compiladas para dispositivos que executam o Windows 10.

Para algumas estruturas de destino, como o .NET Framework, as APIs são definidas pelos assemblies que a estrutura instala em um sistema e pode incluir as APIs da estrutura do aplicativo (por exemplo, ASP.NET).

Para estruturas de destino com base em pacote (por exemplo, .NET 5+, .NET Core e .NET Standard), as APIs são definidas pelos pacotes NuGet incluídos no aplicativo ou na biblioteca.

Versões mais recentes

A tabela a seguir define as estruturas de destino mais comuns, como elas são referenciadas e qual versão do .NET Standard elas implementam. Estas versões de estrutura de destino são as versões estáveis mais recentes. As versões de pré-lançamento não são mostradas. Um TFM (moniker da estrutura de destino) é um formato de token padronizado para especificar a estrutura de destino de um aplicativo ou uma biblioteca do .NET.

Estrutura de destino Mais recente
versão estável
TFM (Moniker de Estrutura de Destino) Implementado
Versão do .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 N/D
.NET Core 3.1 netcoreapp3.1 2.1
.NET Framework 4.8.1 net481 2,0

Estruturas de destino com suporte

Normalmente, uma estrutura de destino é referenciada por um TFM. A tabela a seguir mostra as estruturas de destino com suporte pelo SDK do .NET e o cliente do NuGet. Equivalentes estão mostrados entre colchetes. Por exemplo, win81 é um TFM equivalente ao netcore451.

Estrutura de Destino TFM
.NET 5+ (e .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 Store netcore [netcore45]
netcore45 [win] [win8]
netcore451 [win81]
.NET Micro Framework netmf
Silverlight sl4
sl5
Windows Phone wp [wp7]
wp7
wp75
wp8
wp81
wpa81
Plataforma Universal do Windows uap [uap10.0]
uap10.0 [win10] [netcore50]

*.NET 5 e TFMs posteriores incluem algumas variações específicas do sistema operacional. Para saber mais, confira a seção a seguir, TFMs específicas ao sistema operacional .NET 5+.

TFMs específicas ao sistema operacional .NET 5+

Os TFMs net5.0, net6.0, net7.0 e net8.0 incluem tecnologias que funcionam em diferentes plataformas. Especificar um TFM específico ao sistema operacional torna as APIs específicas a um sistema operacional disponíveis para seu aplicativo, por exemplo, Windows Forms ou associações iOS. As TFMs específicas ao sistema operacional também herdam todas as API disponíveis para a TFM base, por exemplo, a TFM net6.0.

O .NET 5 introduziu o TFM específico ao sistema operacional net5.0-windows, que inclui associações específicas do Windows para WinForms, WPF e APIs UWP. O .NET 6 e versões posteriores têm TFMs adicionais específicos do sistema operacional, por exemplo, net6.0-ios.

A tabela a seguir mostra a compatibilidade das TFMs do .NET 5+.

TFM Compatível com
net5.0 net1.4 (com o aviso NU1701)
netcoreapp1.3.1 (aviso quando WinForms ou WPF é referenciado)
netstandard1.2.1
net5.0-windows netcoreapp1.3.1 (além de tudo que é herdado de net5.0)
net6.0 (Versão seguinte de net5.0)
net6.0-android xamarin.android (e todo o restante herdado de net6.0)
net6.0-ios xamarin.ios (e todo o restante herdado de net6.0)
net6.0-maccatalyst xamarin.ios (e todo o restante herdado de net6.0)
net6.0-macos xamarin.mac (e todo o restante herdado de net6.0)
net6.0-tvos xamarin.tvos (e todo o restante herdado de net6.0)
net6.0-windows (Versão seguinte de net5.0-windows)
net7.0 (Versão seguinte de net6.0)
net7.0-android (Versão seguinte de net6.0-android)
net7.0-ios (Versão seguinte de net6.0-ios)
net7.0-maccatalyst (Versão seguinte de net6.0-maccatalyst)
net7.0-macos (Versão seguinte de net6.0-macos)
net7.0-tizen tizen40 (e todo o restante herdado de net7.0)
net7.0-tvos (Versão seguinte de net6.0-tvos)
net7.0-windows (Versão seguinte de net6.0-windows)
net8.0 (Versão seguinte de net7.0)
net8.0-android (Versão seguinte de net7.0-android)
net8.0-browser Tudo herdado de net8.0
net8.0-ios (Versão seguinte de net7.0-ios)
net8.0-maccatalyst (Versão seguinte de net7.0-maccatalyst)
net8.0-macos (Versão seguinte de net7.0-macos)
net8.0-tizen (Versão seguinte de net7.0-tizen)
net8.0-tvos (Versão seguinte de net7.0-tvos)
net8.0-windows (Versão seguinte de net7.0-windows)

Para tornar seu aplicativo portátil em diferentes plataformas, mas ainda ter acesso a APIs específicas ao sistema operacional, você pode direcionar vários TFMs específicos ao sistema operacional e adicionar proteções de plataforma em chamadas de API específicas ao sistema operacional usando as diretivas de pré-processador #if. Para obter uma lista dos símbolos disponíveis, consulte Símbolos de pré-processador.

Destinos sugeridos

Use estas diretrizes para determinar qual TFM usar em seu aplicativo:

  • Os aplicativos portáteis para várias plataformas devem ter como destino um TFM base, por exemplo net8.0. Isso inclui a maioria das bibliotecas, mas também ASP.NET Core e Entity Framework.

  • As bibliotecas específicas da plataforma devem ter como destino os tipos específicos de plataforma. Por exemplo, projetos WinForms e WPF devem ter como alvo net8.0-windows.

  • Os modelos de aplicativos multiplataforma (Xamarin Forms, ASP.NET Core) e pacotes de ponte (Xamarin Essentials) devem, pelo menos, ter como destino o TFM base, por exemplo, net8.0, mas também podem direcionar tipos adicionais específicos à plataforma para ativar mais APIs ou recursos.

Versão do sistema operacional em TFMs

Você também pode especificar uma versão opcional do sistema operacional no final de um TFM específico ao sistema operacional, por exemplo net6.0-ios15.0. A versão indica quais APIs estão disponíveis para seu aplicativo ou biblioteca. Ela não controla a versão do sistema operacional compatível com seu aplicativo ou biblioteca em tempo de execução. Ela é usada para selecionar os assemblies de referência que seu projeto compila e selecionar ativos de pacotes NuGet. Pense nessa versão como a "versão da plataforma" ou a "versão da API do sistema operacional" para diferenciar da versão do sistema operacional em tempo de execução.

Quando um TFM específico ao sistema operacional não especifica explicitamente a versão da plataforma, ele tem um valor implícito que pode ser inferido do TFM base e do nome da plataforma. Por exemplo, o valor padrão da plataforma para iOS no .NET 6 é 15.0, o que significa que net6.0-ios é abreviação para o TFM canônico net6.0-ios15.0. A versão da plataforma implícita para um TFM base mais recente pode ser superior, por exemplo, um TFM net8.0-ios futuro pode ser mapeado para net8.0-ios16.0. A forma abreviada serve apenas para uso em arquivos de projeto e é expandida para a forma canônica pelos destinos de MSBuild do SDK do .NET antes de ser passada para outras ferramentas, como o NuGet.

A tabela a seguir mostra os TPVs (valores de plataforma de destino) padrão para cada versão do .NET.

Versão do .NET Plataforma Default 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

O SDK do .NET foi projetado para dar suporte a APIs recém-lançadas para uma plataforma individual sem uma nova versão do TFM base. Isso permite que você acesse a funcionalidade específica à plataforma sem aguardar uma versão principal do .NET. Você pode obter acesso a essas APIs recém-lançadas incrementando a versão da plataforma no TFM. Por exemplo, se a plataforma iOS adicionou APIs do iOS 15.1 em uma atualização do SDK do .NET 6.0.x, você poderá acessá-las usando o TFM net6.0-ios15.1.

Precedência

Se seu aplicativo fizer referência a um pacote que tenha vários ativos para diferentes TFMs, os ativos que estiverem mais próximos no número da versão terão preferência. Por exemplo, se o seu aplicativo tiver como destino net6.0-ios e o pacote oferecer ativos para net6.0 e net5.0-ios, os ativos net6.0 serão usados. Para mais informações, consulte Precedências.

Suporte a versões mais antigas de sistema operacional

Embora um aplicativo ou biblioteca específico à plataforma seja compilado em APIs de uma versão específica desse sistema operacional, você pode torná-lo compatível com versões anteriores do sistema operacional adicionando a propriedade SupportedOSPlatformVersion ao arquivo de projeto. A propriedade SupportedOSPlatformVersion indica a versão mínima do sistema operacional necessária para executar seu aplicativo ou biblioteca. Se você não especificar explicitamente essa versão mínima do sistema operacional em tempo de execução no projeto, ele assumirá o padrão de versão da plataforma do TFM.

Para que seu aplicativo seja executado corretamente em uma versão mais antiga do sistema operacional, ele não pode chamar APIs que não existem nessa versão do sistema operacional. No entanto, você pode adicionar proteções em torno de chamadas a APIs mais recentes para que elas sejam chamadas somente ao executar em uma versão do sistema operacional que dê suporte a elas. Esse padrão permite que você projete seu aplicativo ou biblioteca para dar suporte à execução em versões mais antigas do sistema operacional, aproveitando a funcionalidade mais recente do sistema operacional ao executar em versões mais recentes do sistema operacional.

O valor SupportedOSPlatformVersion (seja explícito ou padrão) é usado pelo analisador de compatibilidade da plataforma, que detecta e avisa sobre chamadas desprotegidas para APIs mais recentes. Ele é gravado no assembly compilado do projeto como um atributo de assembly UnsupportedOSPlatformAttribute, para que o analisador de compatibilidade da plataforma possa detectar chamadas desprotegidas para as APIs desse assembly de projetos com um valor de SupportedOSPlatformVersion menor. Em algumas plataformas, o valor SupportedOSPlatformVersion afeta os processos de empacotamento e compilação de aplicativos específicos à plataforma, que são abordados na documentação dessas plataformas.

Aqui está um trecho de exemplo de um arquivo de projeto que usa as propriedades MSBuild TargetFramework e SupportedOSPlatformVersion para especificar que o aplicativo ou biblioteca tenha acesso às APIs do iOS 15.0, mas dá suporte à execução no iOS 13.0 e superior:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0-ios15.0</TargetFramework>
    <SupportedOSPlatformVersion>13.0</SupportedOSPlatformVersion>
  </PropertyGroup>
  ...

</Project>

Como especificar uma estrutura de destino

As estruturas de destino são especificadas em um arquivo de projeto. Quando uma única estrutura de destino for especificada, use o elemento TargetFramework. O seguinte arquivo de projeto de aplicativo de console demonstra como direcionar o .NET 8:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>

</Project>

Ao especificar várias estruturas de destino, você pode fazer referência a assemblies para cada estrutura de destino de forma condicional. Em seu código, você pode condicionalmente compilar em relação a esses assemblies usando símbolos de pré-processador com a lógica if-then-else.

O seguinte projeto de biblioteca tem como destino as APIs do .NET Standard (netstandard1.4) e do .NET Framework (net40 e net45). Use o elemento TargetFrameworks plural com várias estruturas de destino. Os atributos Condition incluem pacotes específicos de implementação quando a biblioteca é compilada para os dois TFMs de .NET Framework:

<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>

No aplicativo ou na biblioteca, você escreve código condicional usando diretivas de pré-processador para compilar para cada estrutura de destino:

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
    }
}

Símbolos de pré-processador

O sistema de build reconhece os símbolos de pré-processador que representam as estruturas de destino mostradas na tabela Versões de estrutura de destino com suporte quando você usa projetos no estilo SDK. Para converter um TFM do .NET Standard, .NET Core ou .NET 5+ em um símbolo de pré-processador, substitua os pontos e hifens por um sublinhado e altere as letras minúsculas para maiúsculas (por exemplo, o símbolo de netstandard1.4 é NETSTANDARD1_4).

Você pode desabilitar a geração desses símbolos por meio da propriedade DisableImplicitFrameworkDefines. Para saber mais sobre essa propriedade, confira DisableImplicitFrameworkDefines.

A lista completa de símbolos de pré-processador para estruturas de destino do .NET é:

Frameworks de destino Símbolos Símbolos adicionais
(disponível em SDKs do .NET 5+)
Símbolos de plataforma (disponíveis somente
quando você especifica um TFM específico do sistema operacional)
.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+ (e .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] (por exemplo, IOS15_1),
[OS][version]_OR_GREATER (por exemplo, IOS15_1_OR_GREATER)

Observação

  • Os símbolos sem versão são definidos independentemente da versão para a qual você está direcionando.
  • Os símbolos específicos à versão são definidos apenas para a versão que você está direcionando.
  • Os símbolos <framework>_OR_GREATER são definidos para a versão que você está direcionando e todas as versões anteriores. Por exemplo, se você estiver direcionando .NET Framework 2.0, os seguintes símbolos serão definidos: NET20, NET20_OR_GREATER, NET11_OR_GREATER e NET10_OR_GREATER.
  • Os símbolos NETSTANDARD<x>_<y>_OR_GREATER são definidos apenas para destinos .NET Standard, e não para destinos que implementam o .NET Standard, como o .NET Core e o .NET Framework.
  • Eles são diferentes dos TFMs (Moniker da Estrutura de Destino) usados pela propriedade MSBuild TargetFramework e pelo NuGet.

Estruturas de destino preteridas

As seguintes estruturas de destino estão preteridas. Os pacotes direcionados a essas estruturas de destino devem ser migrados para as substituições indicadas.

TFM preterido Substituição
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

Confira também