O C# 14 é a versão da linguagem que acompanha o .NET 10, e você pode experimentá-la com o SDK do .NET 10 ou o Visual Studio mais recente. Em vez de uma lista gigante de recursos, quero focar em duas mudanças que realmente aparecem no código de todo dia em projetos backend: os novos extension members (membros de extensão) e a palavra-chave contextual field. As duas atacam o mesmo inimigo: o código repetitivo que a gente escreve no automático.
Extension members: além dos métodos de extensão
Métodos de extensão existem no C# há muito tempo e são a base de bibliotecas como o LINQ. O problema é que, até agora, só dava para estender um tipo com métodos. Se você quisesse uma “propriedade de extensão” ou um operador, não tinha jeito. O C# 14 resolve isso com uma sintaxe nova: o bloco extension.
A ideia é agrupar, dentro de uma classe estática, um bloco que declara o tipo receptor uma única vez. Compare a forma tradicional com a nova:
Antes
public static class EnumerableExtensions
{
public static bool IsEmpty<T>(this IEnumerable<T> source)
=> !source.Any();
}
Agora, com bloco de extensão
public static class EnumerableExtensions
{
extension<T>(IEnumerable<T> source)
{
// propriedade de extensão
public bool IsEmpty => !source.Any();
// método de extensão
public IEnumerable<T> WhereNotNull()
=> source.Where(x => x is not null);
}
}
Repare que o receptor (source) e o parâmetro genérico saem da assinatura de cada método e passam para o cabeçalho do bloco. Some-se a isso o fato de que agora dá para declarar uma propriedade (IsEmpty) chamada como se fosse instância: lista.IsEmpty. Fica muito mais natural do que lista.IsEmpty().
Há também os membros estáticos de extensão. Você declara um bloco que menciona apenas o tipo receptor, sem uma variável, e passa a poder adicionar métodos, propriedades e até operadores estáticos ao próprio tipo:
extension<T>(IEnumerable<T>)
{
public static IEnumerable<T> operator +(
IEnumerable<T> left, IEnumerable<T> right)
=> left.Concat(right);
}
A grande sacada é que a sintaxe antiga continua válida. Você adota os blocos de extensão quando fizer sentido, sem precisar reescrever tudo.
Vale um aviso honesto: nem todo método de extensão migra de forma mecânica para a nova sintaxe, e o suporte das ferramentas foi amadurecendo ao longo das prévias do .NET 10. Ou seja, adote com calma em bibliotecas já consolidadas.
A palavra-chave field: menos campo de apoio na mão
Quem valida valor dentro de um set conhece a dança: declarar um campo privado _algumaCoisa só para dar suporte a uma propriedade. O C# 14 introduz a palavra-chave contextual field, que representa um campo de apoio gerado pelo próprio compilador.
Antes
private string _message;
public string Message
{
get => _message;
set => _message = value
?? throw new ArgumentNullException(nameof(value));
}
Agora
public string Message
{
get;
set => field = value
?? throw new ArgumentNullException(nameof(value));
}
O get; continua automático e só o set ganha lógica, referenciando o campo sintetizado via field. Você pode escrever corpo para um ou para os dois acessadores.
Um detalhe de convivência: se o seu tipo já tiver um símbolo chamado field, pode haver confusão. Nesses casos, use @field ou this.field para desambiguar, ou simplesmente renomeie o símbolo antigo.
Bônus: atribuição condicional a nulo
Ainda no espírito de enxugar guardas repetitivas, os operadores ?. e ?[] agora podem aparecer no lado esquerdo de uma atribuição. Em vez de checar nulo antes de atribuir:
if (customer is not null)
customer.Order = GetCurrentOrder();
Você escreve:
customer?.Order = GetCurrentOrder();
O lado direito só é avaliado quando o receptor não é nulo, então GetCurrentOrder() nem chega a ser chamado se customer for nulo. Também funciona com atribuições compostas como +=, mas não com ++ e --.
Vale a pena migrar?
Nenhum desses recursos é revolucionário isoladamente, mas juntos eles reduzem ruído e deixam a intenção do código mais evidente, o que ajuda em manutenção e revisão. Para times que já estão no .NET 10, os membros de extensão e o field são adoções de baixo risco e retorno imediato em legibilidade. Comece por código novo e por utilitários pequenos antes de mexer em bibliotecas críticas.
Fontes