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:


José Carlos Macoratti