C# - Tipos locais de arquivo
Hoje vou apresentar o recurso do C# 11 chamado de tipos locais de arquivo ou File Local types. |
Você
já desenvolveu ou consumiu objetos com nomes idênticos e quebrou a cabeça
encapsulando esses objetos em diferentes namespaces para evitar colisões de tipo
em tempo de compilação ?
No C# 11 inclui um recurso que vai facilitar a sua vida nestes cenários.
Apresentando o cenário
Vamos supor que temos classes que usam internamente objetos que serão usados apenas em um contexto específico, ou seja, não serão usados no mesmo assembly ou fora dele.
O C# 11 agora permite que você use objetos visíveis apenas dentro do mesmo arquivo e reutilize o mesmo nome de tipo (nome de classe) no mesmo assembly sem conflito.
Considere o seguinte DTO genérico :
public
class
PessoaDTO { public string Nome { get; set; } public string Sobrenome { get; set; } } |
Agora considere que esse DTO pode ser consumido por duas implementações diferentes para dar suporte à identidade de uma pessoa, por exemplo, via SQL e HTTP.
Essas duas implementações usarão internamente um objeto Pessoa que terá o mesmo nome, mas não a mesma representação, por exemplo a primeira com duas propriedades Nome e Sobrenome enquanto a segunda terá apenas uma propriedade chamada NomeSobrenome.
Como esses objetos não são usados em nenhum outro lugar além da classe SQL ou HTTP que processará um objeto Pessoa, torna-se interessante com o C# 11 poder isolá-los no arquivo atual onde são usados para evitar um conflito de nomenclatura entre dois objetos Pessoa.
A palavra-chave file, que é um modificador de tipo, isola a classe Pessoa no arquivo atual onde ela é declarada da seguinte forma:
1- SQLProcessaPessoa
file
class
Pessoa { public string Nome { get; set; } public string Sobrenome { get; set; } } public class SQLProcessaPessoa{ public Task Processa(PessoaDTO pessoaDto) { var person = new Pessoa { Nome = pessoaDto.Nome, Sobrenome = pessoaDto.Sobrenome }; // ... seu código return Task.CompletedTask; } } |
2- HttpProcessaPessoa
file
class
Pessoa { public string Sobrenome { get; set; } } public class HttpProcessaPessoa{ public Task Processa(PessoaDTO pessoaDto) { var pessoa = new Pessoa { NomeSobrenome = $"{pessoaDto.Nome} {pessoa.Sobrenome}" }; // ... seu código return Task.CompletedTask; } } |
Usando este recurso se você compilar seu código, não terá nenhum erro, porque cada classe Pessoa é isolada no arquivo onde esta declarada.
Antes do C# 11, se você tivesse usado os modificadores públicos ou internos, teria ocorrido a seguinte mensagem de erro (para um namespace idêntico):
Error CS0101 The namespace ‘DemoDotnet.Exemplo’ already contains a definition for ‘Pessoa’
Comparação com outros modificadores de acessibilidade :
Boas práticas
1- Use file para
classes auxiliares, interfaces ou tipos internos que não precisam ser expostos a
outros arquivos.
2- Combine com internal ou
private para organizar melhor o código.
3- Prefira file
em projetos com muitas classes de suporte que são específicas para
implementações locais.
E estamos conversados.
"Nada façais por contenda ou por vanglória, mas por humildade; cada um considere
os outros superiores a si mesmo."
Filipenses 2:3
Referências: