Novidades no .NET 6

O .NET 6 fornece as partes finais do plano de unificação do .NET que começou com o .NET 5. O .NET 6 unifica o SDK, as bibliotecas base e o runtime em aplicativos móveis, para desktop, IoT e na nuvem. Além dessa unificação, o ecossistema do .NET 6 oferece:

  • Desenvolvimento simplificado: começar é fácil. Novos recursos de linguagem no C# 10 reduzem a quantidade de código que você precisa escrever. E os investimentos na pilha da Web e as APIs mínimas facilitam a gravação rápida de microsserviços menores e mais rápidos.

  • Melhor desempenho: o .NET 6 é a estrutura da Web de pilha completa e mais rápida, o que reduz os custos de computação se você estiver executando na nuvem.

  • Produtividade final: o .NET 6 e o Visual Studio 2022 fornecem recarregamento frequente, novas ferramentas git, edição de código inteligente, ferramentas robustas de diagnóstico e teste e melhor colaboração em equipe.

O .NET 6 terá suporte por três anos como uma versão LTS (suporte de longo prazo).

Os recursos de versão prévia estão desabilitados por padrão. Também não há suporte para usá-los em produção, e podem ser removidos em uma versão futura. O novo RequiresPreviewFeaturesAttribute é usado para anotar APIs de versão prévia e um analisador correspondente alerta você se você estiver usando essas APIs de versão prévia.

O .NET 6 tem suporte no Visual Studio 2022 e no Visual Studio 2022 para Mac (e versões posteriores).

Este artigo não aborda todos os novos recursos do .NET 6. Para ver todos os novos recursos e para obter mais informações sobre os recursos listados neste artigo, confira a postagem no blog Anúncio do .NET 6.

Desempenho

O .NET 6 inclui várias melhorias de desempenho. Esta seção lista algumas das melhorias em FileStream, otimização guiada por perfil e compilação AOT. Para obter informações detalhadas, confira a postagem no blog Aprimoramentos de desempenho no .NET 6.

FileStream

O tipo System.IO.FileStream foi reescrito para o .NET 6 para fornecer melhor desempenho e confiabilidade no Windows. Agora, o FileStream nunca é bloqueado quando criado para E/S assíncrona no Windows. Para saber mais, confira a postagem no blog Aprimoramentos de E/S de arquivo no .NET 6.

Otimização guiada por perfil

É na PGO (otimização guiada por perfil) que o compilador JIT gera o código otimizado em termos dos tipos e caminhos de código usados com mais frequência. O .NET 6 apresenta o PGO dinâmico. O PGO dinâmico funciona de forma estreita com a compilação em camadas para otimizar ainda mais o código com base na instrumentação adicional que é implementada durante a camada 0. O PGO dinâmico é desabilitado por padrão, mas você pode habilitá-lo com a DOTNET_TieredPGOvariável de ambiente. Para saber mais, confira Aprimoramentos de desempenho do JIT.

Crossgen2

O .NET 6 apresenta o Crossgen2, o sucessor do Crossgen, que foi removido. Crossgen e Crossgen2 são ferramentas que fornecem compilação AOT (antecipada) para melhorar o tempo de inicialização de um aplicativo. Crossgen2 é escrito em C# em vez de C++, e pode executar análise e otimização que não eram possíveis com a versão anterior. Para saber mais, confira Conversa sobre Crossgen2.

Suporte ao Arm64

A versão do .NET 6 inclui suporte para sistemas operacionais macOS Arm64 (ou "Apple Silicon") e Windows Arm64, para execução nativa do Arm64 e emulação de x64. Além disso, os instaladores do .NET x64 e Arm64 agora são instalados lado a lado. Para saber mais, confira Suporte do .NET para macOS 11 e Windows 11 para Arm64 e x64.

Recarga Dinâmica

Recarga frequente é um recurso que permite modificar o código-fonte do aplicativo e aplicar instantaneamente essas alterações ao aplicativo em execução. A finalidade do recurso é aumentar sua produtividade evitando reinicializações de aplicativo entre edições. A Recarga frequente está disponível no Visual Studio 2022 e na ferramenta de linha de comando dotnet watch. A Recarga frequente funciona com a maioria dos tipos de aplicativos .NET e para código-fonte em Visual Basic, C# e C++. Para saber mais, confira a postagem de blog sobre Recarga frequente.

.NET MAUI

A interface do usuário de aplicativo multiplataforma do .NET (.NET MAUI) ainda está em versão prévia, com uma versão RC chegando no primeiro trimestre de 2022, e a de GA (disponibilidade geral) no segundo trimestre de 2022. O .NET MAUI possibilita a criação de aplicativos cliente nativos para sistemas operacionais móveis e para desktop com uma única base de código. Para saber mais, confira a postagem no blog Atualização na interface do usuário de aplicativo multiplataforma do .NET .

C# 10 e modelos

O C# 10 inclui inovações, como diretivas global using, declarações de namespace com escopo de arquivo e structs de registro. Para saber mais, confira Novidades do C# 10.

Em conjunto com esse trabalho, os modelos de projeto do SDK do .NET para C# foram modernizados para usar alguns dos novos recursos de linguagem:

  • Método async Main
  • Instruções de nível superior
  • Expressões new com tipo de destino
  • Diretivas implícitas global using
  • Namespaces com escopo de arquivo
  • Tipos de referência anuláveis

Ao adicionar esses novos recursos de linguagem aos modelos de projeto, o novo código começa com os recursos habilitados. No entanto, o código existente não é afetado quando você atualiza para o .NET 6. Para saber mais sobre essas alterações de modelo, confira a postagem no blog SDK .NET: modelos de projeto em C# modernizados.

F# e Visual Basic

O F# 6 adiciona várias melhorias à linguagem F# e ao F# Interativo. Para saber mais, confira Novidades do F# 6.

O Visual Basic tem melhorias na experiência do Visual Studio e na inicialização do projeto do Windows Forms.

Cargas de trabalho do SDK

Para manter o tamanho menor do SDK do .NET, alguns componentes foram colocados em cargas de trabalho do SDK novas e opcionais. Esses componentes incluem o .NET MAUI e o Blazor WebAssembly AOT. Se você usar o Visual Studio, ele cuidará da instalação de todas as cargas de trabalho do SDK necessárias. Se você usar a CLI do .NET, poderá gerenciar cargas de trabalho usando os novos comandos dotnet workload:

Comando Descrição
dotnet workload search Pesquisa cargas de trabalho disponíveis.
dotnet workload install Instala uma carga de trabalho especificada.
dotnet workload uninstall Remove uma carga de trabalho especificada.
dotnet workload update Atualiza cargas de trabalho instaladas.
dotnet workload repair Reinstala todas as cargas de trabalho instaladas para reparar uma instalação interrompida.
dotnet workload list Lista as cargas de trabalho instaladas.

Para saber mais, confira Cargas de trabalho de SDK opcionais.

APIs System.Text.Json

Muitas melhorias foram feitas em System.Text.Json no .NET 6, de modo que, agora, ele é uma solução de serialização de "força industrial".

Gerador de origem

O .NET 6 adiciona um novo gerador de origem para System.Text.Json. A geração de origem funciona com JsonSerializer e pode ser configurada de várias maneiras. Ela pode melhorar o desempenho, reduzir o uso de memória e facilitar o corte do assembly. Para saber mais, confira Como escolher reflexão ou geração de origem em System.Text.Json e Como usar a geração de origem no System.Text.Json.

DOM gravável

Um novo DOM (modelo de objeto de documento) gravável foi adicionado, o que complementa o DOM somente leitura pré-existente. A nova API fornece uma alternativa leve de serialização para casos em que o uso de tipos POCO (objeto CLR básico) não é possível. Ela também permite que você navegue com eficiência até uma subseção de uma árvore JSON grande e leia uma matriz ou desserialize um POCO a partir dessa subseção. Os novos tipos a seguir foram adicionados para dar suporte ao DOM gravável:

Para saber mais, confira Opções de DOM JSON.

Serialização IAsyncEnumerable

Agora, System.Text.Json dá suporte à serialização e à desserialização com instâncias IAsyncEnumerable<T>. Os métodos de serialização assíncrona enumeram todas as instâncias de IAsyncEnumerable<T> em um grafo de objetos e, em seguida, as serializam como matrizes JSON. Para desserialização, o novo método JsonSerializer.DeserializeAsyncEnumerable<TValue>(Stream, JsonSerializerOptions, CancellationToken) foi adicionado. Para saber mais, confira Serialização IAsyncEnumerable.

Outras APIs novas

Novas interfaces de serialização para validação e valores padrão:

Para saber mais, confira Retornos de chamada.

Novo atributo de ordenação de propriedade:

Novo método para escrever JSON "bruto":

Serialização e desserialização síncrona para um fluxo:

Nova opção para ignorar um objeto quando um ciclo de referência é detectado durante a serialização:

Para saber mais sobre serialização e desserialização com System.Text.Json, confira Serialização e desserialização JSON no .NET.

HTTP/3

O .NET 6 inclui suporte de versão prévia para HTTP/3, uma nova versão do HTTP. O HTTP/3 resolve alguns desafios funcionais e de desempenho existentes usando um novo protocolo de conexão subjacente chamado QUIC. O QUIC estabelece conexões mais rapidamente, e essas conexões são independentes do endereço IP, permitindo que os clientes móveis percorram redes Wi-fi e celular. Para saber mais, confira Usar HTTP/3 com HttpClient.

ASP.NET Core

O ASP.NET Core inclui melhorias em APIs mínimas, compilação AOT (antecipada) para aplicativos Blazor WebAssembly e aplicativos de página única. Além disso, os componentes do Blazor agora podem ser renderizados do JavaScript e integrados com aplicativos baseados em JavaScript existentes. Para saber mais, confira Novidades no ASP.NET Core 6.

OpenTelemetry

O .NET 6 traz suporte aprimorado para OpenTelemetry, que é uma coleção de ferramentas, APIs e SDKs que ajudam você a analisar o desempenho e o comportamento do software. As APIs no namespace System.Diagnostics.Metrics implementam a especificação da API de Métricas do OpenTelemetry. Por exemplo, há quatro classes de instrumento para dar suporte a diferentes cenários de métricas. As classes de instrumento são:

Segurança

O .NET 6 adiciona suporte de versão prévia para duas mitigações de segurança principais: CET (Tecnologia de Imposição de fluxo de controle) e "execução exclusiva de gravação" (W^X).

O CET é uma tecnologia Intel disponível em alguns processadores Intel e AMD mais recentes. Ele adiciona funcionalidades ao hardware que protegem contra alguns ataques de sequestro de fluxo de controle. O .NET 6 fornece suporte para CET para aplicativos Windows x64 e você deve habilitá-lo explicitamente. Para saber mais, confira Compatibilidade do .NET 6 com pilhas de sombra do Intel CET.

O W^X está disponível em todos os sistemas operacionais com o .NET 6, mas está habilitado apenas por padrão no Apple Silicon. O W^X bloqueia o caminho de ataque mais simples, não permitindo que páginas de memória sejam graváveis e executáveis ao mesmo tempo.

Corte de IL

O corte de implantações independentes autocontidas foi aprimorado. No .NET 5, apenas assemblies não utilizados foram cortados. O .NET 6 também adiciona o corte de tipos e membros não utilizados. Além disso, os avisos de corte, que alertam você sobre os locais onde o corte pode remover o código usado em tempo de execução, agora estão habilitados por padrão. Para obter mais informações, confira Cortar implantações e executáveis autocontidos.

Análise de código

O SDK do .NET 6 inclui um punhado de novos analisadores de código relacionados à compatibilidade da API, compatibilidade da plataforma, segurança de corte, uso de extensão na concatenação e divisão de cadeia de caracteres, APIs de cadeia de caracteres mais rápidas e APIs de coleção mais rápidas. Para obter uma lista completa de analisadores novos (e removidos), confira Versões do Analisador – .NET 6.

Proteções de plataforma personalizadas

O Analisador de compatibilidade de plataforma reconhece os métodos Is<Platform> na classe OperatingSystem, por exemplo, OperatingSystem.IsWindows()como proteções de plataforma. Para permitir proteções de plataforma personalizadas, o .NET 6 introduz dois novos atributos que você pode usar para anotar campos, propriedades ou métodos com um nome de plataforma com ou sem suporte:

Windows Forms

Application.SetDefaultFont(Font) é um novo método no .NET 6 que define a fonte padrão em seu aplicativo.

Os modelos para aplicativos de Windows Forms em C# foram atualizados para dar suporte a diretivas global using, namespaces com escopo de arquivo e tipos de referência anuláveis. Além disso, incluem o código de inicialização do aplicativo, que reduz o código clichê e permite que o designer do Windows Forms renderize a superfície de design na fonte preferencial. O código de inicialização é uma chamada para ApplicationConfiguration.Initialize(), que é um método gerado pela origem que emite chamadas para outros métodos de configuração, como Application.EnableVisualStyles(). Além disso, se você definir uma fonte não padrão por meio da propriedade ApplicationDefaultFont do MSBuild, ApplicationConfiguration.Initialize() emitirá uma chamada para SetDefaultFont(Font).

Para saber mais, confira a postagem no blog Novidades no Windows Forms.

Build de origem

O tarball de origem, que contém toda a origem do SDK do .NET, agora é um produto do build do SDK do .NET. Outras organizações, como o Red Hat, podem criar sua própria versão do SDK usando esse tarball de origem.

Monikers da Estrutura de Destino

Os TFMs (Monikers da Estrutura de Destino) adicionais específicos ao sistema operacional foram adicionados para .NET 6, por exemplo, net6.0-android, net6.0-ios e net6.0-macos. Para saber mais, confira TFMs específicos ao sistema operacional .NET 5+.

Matemática genérica

Está em versão prévia a capacidade de usar operadores em tipos genéricos no .NET 6. O .NET 6 apresenta várias interfaces que usam a nova versão prévia do recurso do C# 10, membros da interface static abstract. Essas interfaces correspondem a operadores diferentes, por exemplo, IAdditionOperators representa o operador +. As interfaces estão disponíveis no pacote NuGet System.Runtime.Experimental. Para saber mais, confira a postagem no blog Matemática genérica.

Validação do pacote NuGet

Se você for um desenvolvedor de biblioteca do NuGet, a nova ferramenta de validação de pacote permitirá que você valide se os pacotes são consistentes e bem formados. Você pode determinar se:

  • Há alterações significativas nas versões do pacote.
  • O pacote tem o mesmo conjunto de APIs públicas para todas as implementações específicas ao runtime.
  • Há lacunas para aplicabilidade de estrutura de destino ou runtime.

Para saber mais, confira a postagem no blog Validação do pacote.

APIs de reflexão

O .NET 6 apresenta as seguintes APIs novas que inspecionam o código e fornecem informações de nulidade:

Essas APIs são úteis para ferramentas e serializadores baseados em reflexão.

APIs de Microsoft.Extensions

Vários namespaces de extensões receberam melhorias no .NET 6, como mostra a tabela a seguir.

Namespace Aprimoramentos
Microsoft.Extensions.DependencyInjection CreateAsyncScope permite que você use com segurança uma instrução using para um provedor de serviços que registra um serviço IAsyncDisposable.
Microsoft.Extensions.Hosting Novos métodos ConfigureHostOptions simplificam a configuração do aplicativo.
Microsoft.Extensions.Logging Microsoft.Extensions.Logging tem um novo gerador de origem para APIs de registro em log com desempenho. O gerador de origem é disparado se você adicionar o novo LoggerMessageAttribute a um método de registro em log partial. No tempo de compilação, o gerador gera a implementação do método partial, que normalmente é mais rápido em tempo de execução do que as soluções de log existentes. Para saber mais, confira Geração de origem de registro em log em tempo de compilação.

Novas APIs LINQ

Vários métodos LINQ foram adicionados ao .NET 6. A maioria dos métodos novos listados na tabela a seguir tem métodos equivalentes ao tipo System.Linq.Queryable.

Método Descrição
Enumerable.TryGetNonEnumeratedCount<TSource>(IEnumerable<TSource>, Int32) Tenta determinar o número de elementos em uma sequência sem forçar uma enumeração.
Enumerable.Chunk<TSource>(IEnumerable<TSource>, Int32) Divide os elementos de uma sequência em partes com tamanho especificado.
Enumerable.MaxBy e Enumerable.MinBy Localiza elementos máximos ou mínimos usando um seletor de chave.
Enumerable.DistinctBy, Enumerable.ExceptBy, Enumerable.IntersectBy e Enumerable.UnionBy Essas novas variações de métodos que executam operações baseadas em conjunto permitem que você especifique a igualdade usando uma função seletora de chave.
Enumerable.ElementAt<TSource>(IEnumerable<TSource>, Index) e Enumerable.ElementAtOrDefault<TSource>(IEnumerable<TSource>, Index) Aceita índices contados desde o início ou final da sequência, por exemplo, Enumerable.Range(1, 10).ElementAt(^2) retorna 9.
Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, TSource) e Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)
Enumerable.LastOrDefault<TSource>(IEnumerable<TSource>, TSource) e Enumerable.LastOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)
Enumerable.SingleOrDefault<TSource>(IEnumerable<TSource>, TSource) e Enumerable.SingleOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)
Novas sobrecargas permitem que você especifique um valor padrão a ser usado se a sequência estiver vazia.
Enumerable.Max<TSource>(IEnumerable<TSource>, IComparer<TSource>) e Enumerable.Min<TSource>(IEnumerable<TSource>, IComparer<TSource>) Novas sobrecargas permitem que você especifique um comparador.
Enumerable.Take<TSource>(IEnumerable<TSource>, Range) Aceita um argumento Range para simplificar a tomada de uma fatia de uma sequência. Por exemplo, você pode usar source.Take(2..7) em vez de source.Take(7).Skip(2).
Enumerable.Zip<TFirst,TSecond,TThird>(IEnumerable<TFirst>, IEnumerable<TSecond>, IEnumerable<TThird>) Produz uma sequência de tuplas com elementos de três sequências especificadas.

Melhorias de data, hora e fuso horário

Os dois structs a seguir foram adicionados ao .NET 6: System.DateOnly e System.TimeOnly. Eles representam a parte de data e a parte de hora de um DateTime, respectivamente. DateOnly é útil para aniversários e aniversários de casamento, e TimeOnly é útil para alarmes diários e horário comercial semanal.

Agora, você pode usar as IDs de IANA (Autoridade de Números Atribuídos à Internet) ou do fuso horário do Windows em qualquer sistema operacional que tenha dados de fuso horário instalados. O método TimeZoneInfo.FindSystemTimeZoneById(String) foi atualizado para converter automaticamente sua entrada de um fuso horário do Windows em um fuso horário IANA (ou vice-versa), se o fuso horário solicitado não for encontrado no sistema. Além disso, os novos métodos TryConvertIanaIdToWindowsId(String, String) e TryConvertWindowsIdToIanaId foram adicionados para cenários em que você ainda precisa converter manualmente de um formato de fuso horário para outro.

Também há algumas outras melhorias de fuso horário. Para saber mais, confira Aprimoramentos de data, hora e fuso horário no .NET 6.

Classe PriorityQueue

A nova classe PriorityQueue<TElement,TPriority> representa uma coleção de itens que têm um valor e uma prioridade. Os itens são removidos da fila em ordem de prioridade crescente, ou seja, o item com o valor de prioridade mais baixo é removido da fila primeiro. Essa classe implementa uma estrutura de dados de heap mínimo.

Confira também