A Nova Palavra-chave field no C# 14
[[academy-video-youtube({"vid": "_Z551_SKHA4", "start_time": "0", "title": "The New field Keyword in C# 14", "creator": "Tim Corey", "length": "10m 35s"})]]
As propriedades automáticas em C# são concisas, mas no momento em que você precisa de validação ou lógica de transformação em um setter, você sempre teve que abandoná-las completamente e escrever uma propriedade completa com um campo de apoio manual. Essa mudança de uma linha para sete é um custo alto para adicionar uma única cláusula de proteção. C# 14 introduz a palavra-chave field para preencher essa lacuna, permitindo que você personalize um getter ou setter enquanto o compilador ainda gerencia o campo de apoio para você.
Em seu vídeo "The New field Keyword in C# 14", Tim Corey demonstra o problema que esse recurso resolve, passa por exemplos práticos de validação de setter e cobre um conflito de nomenclatura que você deve saber antes de atualizar. Vamos seguir cada passo em detalhe para que você possa começar a usar field em suas próprias propriedades com confiança.
A Configuração: Um Modelo de Pessoa Simples
[0:12 - 1:07] Tim começa com um aplicativo de console rodando em .NET 10 e Visual Studio 2026. A demonstração se centra em uma classe Person com algumas propriedades:
public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }
public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }
Há também uma propriedade Demo apoiada por um campo privado, que se torna relevante uma vez que o conflito de nomenclatura surge. Em Program.cs, Tim cria uma instância com FirstName = "Tim" e LastName = "Corey", em seguida, imprime o último nome, idade e valor da demonstração. Tudo é exibido conforme o esperado: "Corey", 0 (o inteiro padrão) e "test".
O Problema: Auto-Propriedades Aceitam Dados Indesejados
[1:23 - 2:49] O problema surge quando Tim atribui null a LastName após a construção:
p.LastName = null;
p.LastName = null;
Mesmo que LastName seja marcado como required e digitado como uma string não nula, a atribuição é compilada. O modificador required apenas reforça que um valor é fornecido durante a inicialização do objeto; não impede que alguém defina a propriedade como null posteriormente. O resultado é um sobrenome em branco em tempo de execução sem que nenhum erro seja lançado.
Isso é uma verdadeira lacuna na integridade dos dados. O sistema de tipos o adverte com uma ondulação de referência anulável, mas isso é uma dica em tempo de compilação, não uma proteção em tempo de execução. Se sua aplicação depende de LastName sempre contendo uma string válida, auto-propriedades sozinhas não podem reforçar esse contrato.
A Solução Antiga: Propriedades Completas com Campos de Apoio Manuais
[2:58 - 4:19] Antes do C# 14, a solução padrão era converter a propriedade automática em uma propriedade completa com um campo de apoio explícito:
private string _lastName;
public required string LastName
{
get => _lastName;
set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}
private string _lastName;
public required string LastName
{
get => _lastName;
set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}
Tim executa isso e confirma que a exceção dispara corretamente: "O valor não pode ser nulo. Nome do parâmetro: LastName." A abordagem funciona, mas requer declarar um campo privado, configurar o getter e o setter e repetir o nome da propriedade em várias linhas. Para uma única regra de validação, isso é uma cerimônia excessiva.
O getter neste caso não faz nada especial; ele retorna o campo inalterado. No entanto, você ainda precisa escrevê-lo explicitamente porque a sintaxe exige ambas as metades uma vez que você sai do território de propriedade automática. Tim enquadra essa verbosidade como a motivação por trás do novo recurso.
A Solução C# 14: A Palavra-chave field
[4:23 - 5:47] O C# 14 introduz um meio-termo. Em vez de declarar um campo de apoio privado você mesmo, você usa a palavra-chave contextual field dentro de um getter ou setter para referenciar diretamente o campo de apoio gerado pelo compilador:
public required string LastName
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}
public required string LastName
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}
O getter permanece um get; auto-implementado sem necessidade de corpo. O setter usa field para atribuir o value de entrada após a validação. O compilador cria e gerencia o campo de apoio nos bastidores, assim como faz com uma propriedade automática padrão.
Executar a demonstração produz o mesmo ArgumentNullException na atribuição nula. O comportamento é idêntico à versão com apoio manual, compactado de sete linhas para um bloco concentrado que apenas personaliza o necessário. Você mantém o getter de propriedade automática, adiciona lógica apenas ao setter e pula completamente a declaração do campo manual.
Isso oferece um estágio intermediário útil entre uma propriedade automática simples (uma linha, sem validação) e uma propriedade completa (sete ou mais linhas, controle completo). Quando sua lógica toca apenas o setter, você não paga mais o custo sintático de reescrever o getter também.
Validando Idade com um Guardião no Setter
[6:16 - 7:39] Para mostrar que field não se limita a verificações de nulidade, Tim adiciona validação de intervalo à propriedade Age:
public int Age
{
get;
set
{
if (value > 0 && value < 120)
field = value;
}
}
public int Age
{
get;
set
{
if (value > 0 && value < 120)
field = value;
}
}
Aqui o setter ignora silenciosamente valores fora de um alcance razoável. Atribuir -5 deixa Age no seu valor padrão de zero porque a condição falha e field nunca é escrita. Tim nota que você poderia lançar uma exceção em vez disso, mas a abordagem silenciosa demonstra que o corpo do setter pode conter qualquer lógica que você precise, enquanto ainda depende de field para armazenamento.
O padrão se aplica amplamente: delimitar intervalos numéricos, remover espaços em branco de strings, normalizar maiúsculas e minúsculas ou qualquer transformação que você queira aplicar toda vez que uma propriedade for configurada.
Conflitos de Nomenclatura com Variáveis campo Existentes
[7:39 - 9:43] Tim introduz um caso especial deliberado. A classe de demonstração tem um membro privado literalmente chamado field:
private string field = "test";
private string field = "test";
Uma vez que C# 14 está ativo, o compilador trata field dentro de um acessador de propriedade como a palavra-chave e não a variável. Isso significa que uma propriedade referenciando field lê silenciosamente do armazenamento oculto atrás da propriedade (que está vazio) em vez do membro string contendo "teste". A saída muda para em branco sem erro de compilação, apenas um aviso.
Existem duas soluções. Prefixar com this.field diz ao compilador que você quer dizer o membro de nível de classe, não a palavra-chave. Alternativamente, a escape @field funciona da mesma forma:
// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;
// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;
A forte recomendação de Tim é renomear quaisquer variáveis chamadas field ao atualizar para C# 14. Um rápido "Renomear Tudo" no seu IDE elimina a ambiguidade permanentemente. O conflito só surge dentro dos acessadores de propriedade; construtores e métodos resolvem field para o nome da variável como esperado, uma vez que esses contextos não têm armazenamento de apoio implícito.
Concluindo: Menos Código Boilerplate, Mesmo Controle
[10:04 - 10:28] A palavra-chave field preenche uma lacuna prática no código C# do dia a dia. Propriedades que necessitam de uma cláusula de guarda ou transformação não exigem mais uma reescrita completa com campos de apoio manuais. Você só personaliza o acessador que precisa de lógica e deixa o outro como uma implementação automática padrão.
Conclusão
[10:28 - 10:35] Recapitulando: A palavra-chave field do C# 14 dá a você acesso direto ao armazenamento de apoio implícito dentro de qualquer acessador de propriedade. Use-o para adicionar validação no setter, transformações no getter, ou ambos, sem abandonar a sintaxe de propriedade automática para as partes que não precisam de personalização.
Antes de atualizar, procure em sua base de código por quaisquer variáveis chamadas field e as renomeie. Essa única precaução evita o único problema real que este recurso introduz. Além disso, é uma redução limpa no boilerplate que se encaixa naturalmente em como a maioria dos desenvolvedores já estrutura seus modelos.
Dica de Exemplo: Se você só precisa validar o setter, deixe o getter como um get; simples sem corpo. O compilador trata como um getter de propriedade automática, e você evita escrever uma instrução de retorno de passagem que não adiciona nada.
Assista ao vídeo completo vídeo no Canal do YouTube dele para obter mais insights sobre os recursos da linguagem C#.
