C# 8.0  -  A declaração using


 Hoje vou apresentar com mais detalhes a instrução switch na versão 8.0 da linguagem C#.

Com a atualização do C# 8.0, a Microsoft introduziu o recurso de declaração using.

Esse recurso nos permite declarar um objeto disposable (descartável) com a palavra-chave using para que o objeto seja descartado (dispose) quando sair do escopo.

Para poder usar os novos recursos basta instalar a última versão do Visual Studio Community 2019 e criar um projeto do tipo Console Application para .NET Core:

Na abordagem clássica, antes da atualização do C# 8.0, usamos uma instrução using para definir o escopo dos objetos de tipo gerenciado que acessam recursos não gerenciados e os recursos não gerenciados que implementam a interface IDisposable.

A seguir temos um exemplo de código usando a abordagem clássica :

static void CriarArquivoTexto()
{
 
  using (var arquivo = new System.IO.StreamWriter("Teste.txt"))
    {
        arquivo.WriteLine("C# 8.0 - using");
    }   // o objeto arquivo era descartado aqui
}
 

Vejamos agora o mesmo exemplo usando a declaração using do C# 8.0 :

static void CriarArquivoTexto()
{
 
  using var arquivo = new System.IO.StreamWriter("Teste.txt");
    arquivo.WriteLine("C# 8.0 - using");
    // o objeto arquivo era descartado aqui
}
 

À primeira vista, percebemos que as chaves {} foram suprimidas, e,  se refatoramos o código e analisarmos o resultado da IL veremos que os dois trechos de código vão gerar o mesmo código final:

static void CriarArquivoTexto()
{
 
  using (StreamWriter arquivo = new StreamWriter("Teste.txt"))
    {
        arquivo.WriteLine("C# 8.0 - using");
    }  
}
 

Com base nisso concluímos que a declaração using não precisa que o escopo do objeto seja definido explicitamente; em vez disso, ele é tratado pelo próprio compilador; ou seja, o escopo do objeto declarado na instrução using é o escopo no qual ele foi declarado.

Vamos considerar o seguinte cenário comparando a instrução using e a declaração using:

1- instrução Using

static int CriarArquivoTexto(List linhas)
{
    int linhasAdicionadas = 0;
    using (var arquivo = new System.IO.StreamWriter("Teste.txt"))
    {
        foreach (string linha in linhas)
            if (line.Contains("teste - linha"))
            {
                arquivo.WriteLine(linha);
                linhasAdicionadas ++;
            }
    }
    return linhasAdicionadas ;
}

2- declaração Using

static int CriarArquivoTexto(List linhas)
{
    int linhasAdicionadas = 0;
  
 using var arquivo = new System.IO.StreamWriter("Teste.txt");
    foreach (string linha in linhas)
        if (line.Contains("teste - linha"))
        {
              arquivo.WriteLine(linha);
               linhasAdicionadas ++;
         }


    return linhasAdicionadas ;
}

Compilando e refatorando o assembly compilado para cada caso temos o resultado abaixo:

1- instrução using
static int CriarArquivoTexto(List linhas)
{
    int linhasAdicionadas = 0;
    using (var arquivo = new System.IO.StreamWriter("Teste.txt"))
    {

        foreach (string linha in linhas)

        {

            if (line.Contains("teste - linha"))
            {
                arquivo.WriteLine(linha);
                linhasAdicionadas ++;
            }
        }
    }
    return linhasAdicionadas ;
}
2- declaração using
static int CriarArquivoTexto(List linhas)
{
    int linhasAdicionadas = 0;
    using (var arquivo = new System.IO.StreamWriter("Teste.txt"))
    {

        foreach (string linha in linhas)
        {
            if (line.Contains("teste - linha"))
            {
                arquivo.WriteLine(linha);
                linhasAdicionadas ++;
            }
        }
        return linhasAdicionadas ;
    }
}

Embora o código final pareça ser semelhante, eles não são.

O escopo do bloco  instrução using é um pouco maior que no bloco da declaração using.

No caso de uma instrução using, temos controle sobre a definição do escopo do objeto.

No caso de uma declaração de using, seu escopo é automaticamente definido a partir da declaração do objeto  até o final do bloco de código atual.

Se os métodos forem pequenos e você estiver usando a declaração using na parte final do método, a nova abordagem vai funcionar da forma que você espera e te poupará algumas linhas de código.

Aguarde mais artigos sobre as novidades do C# 8.0.

"Bom é louvar ao SENHOR, e cantar louvores ao teu nome, ó Altíssimo;
Para de manhã anunciar a tua benignidade, e todas as noites a tua fidelidade;"
Salmos 92:1,2

Referências:


José Carlos Macoratti