.NET 10 Preview 1: O que há de novo na próxima geração do .NET
O .NET 10 Preview 1 foi anunciado pela Microsoft em 25 de fevereiro de 2025 e abriu o ciclo de desenvolvimento da próxima versão LTS da plataforma. A primeira prévia traz otimizações de performance no JIT, novas APIs nas bibliotecas e os primeiros recursos do C# 14.
O objetivo da nova versão é continuar evoluindo o ecossistema .NET, com mais produtividade e melhor suporte a workloads modernos. Além disso, ela melhora a integração com ferramentas nativas de nuvem, como containers.
Neste artigo, exploramos os principais destaques do .NET 10 Preview 1 e como eles podem impactar o desenvolvimento de aplicações.
Performance e otimizações do JIT no .NET 10 Preview 1
A cada nova versão, a Microsoft foca em aprimorar a performance do runtime, e o .NET 10 Preview 1 não é diferente. Nesta prévia, as principais otimizações estão no compilador JIT (Just-In-Time), que gera o código nativo da aplicação.
As notas de lançamento do runtime destacam três frentes. São elas a desvirtualização de métodos de interface em arrays, a alocação de arrays na stack e o suporte ao AVX10.2.
Desvirtualização de interfaces em arrays
Antes, quando você percorria um array através de uma interface como IEnumerable<T>, as chamadas virtuais permaneciam sem otimização. Ou seja, o JIT não conseguia aplicar inlining nesses casos.
No .NET 10 Preview 1, o JIT reconhece esse padrão e elimina as chamadas virtuais. Com isso, um foreach sobre um array convertido para IEnumerable<int> passa a gerar código tão eficiente quanto a iteração direta.
static int Sum(IEnumerable<int> numbers)
{
var total = 0;
// O JIT agora consegue desvirtualizar este loop quando a origem é um array
foreach (var number in numbers)
total += number;
return total;
}
int[] values = [1, 2, 3, 4, 5];
Console.WriteLine(Sum(values));
Essa mudança abre caminho para outras otimizações, como inlining e alocação na stack. Portanto, código que trabalha com abstrações fica mais rápido sem nenhuma alteração.
Alocação de arrays de tipos por valor na stack
Outra otimização permite que o JIT aloque na stack pequenos arrays de tamanho fixo de tipos por valor. A condição é que o array não contenha referências gerenciadas e não sobreviva ao método que o criou.
Por exemplo, um int[] numbers = { 1, 2, 3 }; dentro de um método pode deixar de ir para o heap. Dessa forma, o runtime reduz alocações desnecessárias e diminui a pressão sobre o Garbage Collector.
Suporte ao AVX10.2
O .NET 10 Preview 1 também introduz intrinsics para o conjunto de instruções AVX10.2, em processadores x64. As novas APIs ficam na classe System.Runtime.Intrinsics.X86.Avx10v2.
No entanto, o suporte no JIT vem desabilitado por padrão nesta prévia. Isso acontece porque o hardware com AVX10.2 ainda não estava disponível para testes completos.
E o Garbage Collector?
O Garbage Collector (GC) não recebeu um item próprio nas notas oficiais desta prévia. Contudo, ele se beneficia indiretamente das otimizações do JIT.
Afinal, cada array que vai para a stack em vez do heap é um objeto a menos para o GC coletar. Assim, aplicações com muitas alocações curtas tendem a sentir menos pausas.
As mudanças mais profundas no GC chegaram ao longo do ciclo do .NET 10. Se esse tema interessa, o artigo sobre as mudanças no Garbage Collector do .NET 10 detalha o que mudou na versão final.
Novidades nas bibliotecas do .NET 10 Preview 1
As bibliotecas base receberam uma lista extensa de melhorias no .NET 10 Preview 1. A seguir, estão os destaques mais úteis para o dia a dia.
- Certificados por outros thumbprints:
X509Certificate2Collection.FindByThumbprintaceita SHA-256 ou SHA3-256, e não apenas SHA-1. - PEM em bytes:
PemEncoding.FindUtf8lê dados PEM direto de bytes, sem converter para caracteres. - ISOWeek com DateOnly: novas sobrecargas de
ISOWeek.GetWeekOfYear,ISOWeek.GetYeareISOWeek.ToDateOnly. - Normalização com spans:
GetNormalizedLength,IsNormalizedeTryNormalizetrabalham com spans e evitam novas strings. - Comparação numérica de strings: a opção
CompareOptions.NumericOrderingordena "2" antes de "10". - TimeSpan.FromMilliseconds: nova sobrecarga com um único parâmetro, compatível com expressões LINQ.
Além disso, o OrderedDictionary<TKey, TValue> ganhou sobrecargas de TryAdd e TryGetValue que devolvem o índice do item. Segundo as notas, isso melhorou entre 10% e 20% a performance de atualização de propriedades em operações com JSON.
Comparação numérica de strings
A comparação numérica era um pedido antigo da comunidade. Com ela, você ordena textos que contêm números de forma natural, e não lexicográfica.
using System.Globalization;
var comparer = StringComparer.Create(CultureInfo.CurrentCulture, CompareOptions.NumericOrdering);
string[] versions = ["10", "2", "1", "21"];
foreach (var version in versions.Order(comparer))
Console.WriteLine(version); // 1, 2, 10, 21
Também vale notar que "2" e "02" passam a ser considerados iguais. Por isso, o mesmo comparador funciona bem em HashSet<string> e em verificações de igualdade.
ZipArchive e serialização JSON
O ZipArchive recebeu ganhos expressivos de performance. Segundo as notas oficiais, o modo de atualização teve uma redução de 99,8% no tempo de execução em operações com arquivos de 2 GB.
Nesse mesmo cenário, o uso de memória caiu 99,9996%, e a leitura de arquivos melhorou cerca de 18% nas métricas medidas. O artigo sobre as otimizações no ZipArchive do .NET 10 explora esses números em detalhes.
Já no System.Text.Json, o atributo JsonSourceGenerationOptionsAttribute passou a aceitar um ReferenceHandler. Assim, contextos gerados por source generator conseguem preservar referências cíclicas em vez de lançar exceções.
C# 14 no .NET 10 Preview 1
O .NET 10 Preview 1 traz os primeiros recursos do C# 14, a versão da linguagem que acompanha o .NET 10. Entre eles, o mais aguardado é a palavra-chave field em propriedades.
Propriedades com a palavra-chave field
Com field, você acessa o campo de apoio gerado pelo compilador dentro dos acessores. Dessa forma, não precisa declarar um campo privado só para adicionar uma validação.
public class Product
{
// O compilador cria o campo de apoio, acessado com field
public string Name
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
}
Antes, essa validação exigia transformar a auto-property em uma propriedade completa, com um campo explícito. Portanto, o novo recurso reduz bastante o código repetitivo.
Outros recursos do C# 14 na prévia
Além de field, a prévia trouxe outras novidades na linguagem. Primeiro, o nameof passou a aceitar tipos genéricos sem argumentos, como nameof(List<>).
Em seguida, o C# ganhou conversões implícitas de primeira classe para Span<T> e ReadOnlySpan<T>. Com isso, o código com spans fica mais natural de escrever.
Também ficou possível usar modificadores como ref, in e out em parâmetros de lambdas sem declarar os tipos. Por fim, há um recurso experimental que grava literais de string como UTF-8 em uma seção de dados separada do executável.
SDK e containers no .NET 10 Preview 1
No SDK, a principal novidade do .NET 10 Preview 1 é a poda de referências de pacotes fornecidos pelo framework. O recurso vem habilitado por padrão e remove pacotes que o próprio framework já entrega.
Na prática, isso reduz o trabalho do restore, diminui o arquivo .deps.json e evita falsos positivos no NuGet Audit. Caso precise desativar, use a propriedade RestoreEnablePackagePruning com valor false.
A poda vale para todos os target frameworks do .NET, como net8.0 e net10.0, e para o .NET Standard 2.0 ou superior. Você pode desativá-la no arquivo do projeto ou no Directory.Build.props.
O recurso também traz três novos avisos, chamados NU1509, NU1510 e NU1511. O artigo sobre NuGet package pruning no .NET 10 explica o mais comum deles, o NU1510, em detalhes.
Já nos containers, as imagens de prévia trocaram o Debian pelo Ubuntu 24.04 como sistema padrão. Além disso, as imagens Ubuntu Chiseled agora incluem o manifesto do Chisel, que permite instalar pacotes extras sobre essas imagens enxutas.
ASP.NET Core no .NET 10 Preview 1
O ASP.NET Core também recebeu melhorias significativas, com foco em OpenAPI e Blazor. A mudança mais visível é o suporte à geração de documentos OpenAPI 3.1.
Nesta prévia, a versão 3.1 passou a ser o padrão e trouxe compatibilidade com o JSON Schema 2020-12. Ainda assim, você pode voltar para a 3.0 pela propriedade OpenApiVersion de OpenApiOptions.
Atenção, porque a mudança inclui uma quebra de compatibilidade. A biblioteca OpenAPI.NET subiu para a versão 2.0, e o tipo OpenApiAny deu lugar ao JsonNode.
Além disso, o documento OpenAPI pode ser servido em YAML. Para isso, basta usar uma rota com o sufixo .yaml ou .yml:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
var app = builder.Build();
// Serve o documento OpenAPI em YAML
app.MapOpenApi("/openapi/{documentName}.yaml");
app.Run();
Outras novidades do ASP.NET Core nesta prévia incluem:
- Descrição nas respostas:
ProducesResponseTypeaceita um parâmetroDescriptionpara documentar cada resposta. - Detecção de URL local: o método
RedirectHttpResult.IsLocalUrlajuda a evitar ataques de open redirect. - Testes de integração: um source generator cria a declaração
public partial class Programautomaticamente. - QuickGrid: o novo parâmetro
RowClassaplica classes CSS às linhas conforme os dados. - Script do Blazor: o arquivo passou a ser um static web asset, com compressão e fingerprinting, e caiu de 183 KB para 43 KB, cerca de 76% menor.
Entity Framework Core no .NET 10 Preview 1
O Entity Framework Core também recebeu atualizações que facilitam o desenvolvimento de aplicações orientadas a dados. O destaque é o suporte nativo ao operador LeftJoin no LINQ.
Antes, um left join exigia combinar GroupJoin, SelectMany e DefaultIfEmpty. Agora, a mesma consulta fica bem mais direta:
var query = context.Students
.LeftJoin(
context.Departments,
student => student.DepartmentId,
department => department.Id,
(student, department) => new
{
student.FirstName,
student.LastName,
Department = department.Name ?? "[NONE]"
});
Outra mudança relevante está no ExecuteUpdateAsync, que passou a aceitar lambdas comuns em vez de exigir expression trees. Com isso, você usa if e outras estruturas de controle dentro da atualização em lote.
await context.Blogs.ExecuteUpdateAsync(setters =>
{
setters.SetProperty(blog => blog.Views, 8);
// Atualiza o nome apenas quando necessário
if (nameChanged)
setters.SetProperty(blog => blog.Name, "foo");
});
As notas do EF Core também listam melhorias de tradução e otimização de consultas. Por exemplo, a tradução de DateOnly.ToDateTime, a otimização de cláusulas LIMIT consecutivas e nomes de parâmetros SQL mais simples, como city em vez de @__city_0.
Ao todo, o EF Core 10 Preview 1 reuniu 18 melhorias, 14 correções de regressão e 28 outras correções de bugs. Entre elas, estão a tradução de COUNT sobre ICollection<T> e de MIN e MAX sobre consultas com DISTINCT.
Novidades no .NET MAUI
Para quem desenvolve aplicações multiplataforma com .NET MAUI, a Microsoft focou em qualidade e estabilidade nesta prévia. Entre os destaques, estão melhorias no CollectionView para iOS e Mac Catalyst.
No Android, a prévia adicionou suporte ao Android 16 Beta 1 e ao build com o JDK 21. Além disso, o comando dotnet run passou a funcionar em projetos Android.
Por fim, os avisos do trimmer passaram a vir habilitados por padrão em iOS, Mac Catalyst, macOS e tvOS. Assim, problemas de compatibilidade com trimming aparecem mais cedo no desenvolvimento.
Windows Forms e WPF também receberam atualizações. O Windows Forms ganhou novas APIs de área de transferência e marcou alguns métodos antigos como obsoletos, enquanto o WPF se concentrou em melhorias de qualidade.
O que o .NET 10 Preview 1 ainda não trouxe
Como toda primeira prévia, o .NET 10 Preview 1 é apenas o começo do ciclo. Por isso, áreas como inteligência artificial e observabilidade não tiveram anúncios específicos nesta versão.
O mesmo vale para o Garbage Collector, que evoluiu nas prévias seguintes. Portanto, vale acompanhar cada nova versão para ver como o pacote completo do .NET 10 tomou forma.
Também é importante lembrar que prévias não têm suporte para produção. Assim, use o .NET 10 Preview 1 para testes, protótipos e para preparar seus projetos para a migração.
Como testar o .NET 10 Preview 1
Para experimentar a prévia, baixe o SDK do .NET 10 Preview 1 na página oficial de downloads do .NET. Em seguida, crie um projeto apontando para o novo target framework.
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<!-- Habilita recursos da linguagem ainda em prévia -->
<LangVersion>preview</LangVersion>
</PropertyGroup>
O LangVersion com valor preview libera os recursos do C# 14 disponíveis na prévia. Dessa forma, você consegue testar a palavra-chave field e as demais novidades da linguagem.
Conclusão
O .NET 10 Preview 1 marca o início de uma nova fase para a plataforma, com avanços em performance, novas APIs e os primeiros recursos do C# 14. Além disso, ASP.NET Core, EF Core e .NET MAUI receberam melhorias práticas.
Os destaques ficam com a desvirtualização de arrays no JIT, o OpenAPI 3.1 e o LeftJoin no EF Core. Cada um deles resolve uma dor real de quem desenvolve com .NET.
Se você é desenvolvedor .NET, vale a pena testar essa nova versão e se preparar para as inovações que estão por vir. Afinal, o .NET 10 é uma versão LTS, com suporte estendido.
Fique ligado para mais novidades conforme novas prévias forem lançadas. Com isso, você chega à versão final com o terreno preparado.
Se preferir, o vídeo abaixo também apresenta as novidades do .NET 10 Preview 1.
FAQ
Quando o .NET 10 Preview 1 foi lançado?
A Microsoft anunciou o .NET 10 Preview 1 em 25 de fevereiro de 2025. Ele foi a primeira prévia do ciclo do .NET 10.
Posso usar o .NET 10 Preview 1 em produção?
Não é recomendado. Prévias servem para testes e avaliação, e não contam com suporte para produção.
Qual versão do C# acompanha o .NET 10?
O .NET 10 acompanha o C# 14. A prévia já trazia recursos como a palavra-chave field e o nameof com genéricos sem argumentos.
O que mudou no EF Core nesta prévia?
O destaque é o operador LeftJoin no LINQ. Além disso, o ExecuteUpdateAsync passou a aceitar lambdas comuns.
O .NET 10 é uma versão LTS?
Sim. O .NET 10 é uma versão com suporte de longo prazo.