C# - Apresentando Discards


Hoje vou apresentar o recurso Discards, disponível a partir da versão 7.0 da linguagem C#.

Você já ouviu falar sobre ou já usou o recurso Discards da linguagem C# ?

O recurso Discards ou Descarte em uma tradução livre, são variáveis locais temporárias que são intencionalmente não utilizadas no código de uma aplicação. Elas são equivalentes a variáveis não atribuídas, não possuem nome e não possuem nenhum valor sendo representadas por um sublinhado (_).

O objetivo deste recurso é criar uma forma de jogar fora ou descartar um valor que não será usado no seu código.

Como existe apenas uma única variável discard e ela pode nem ter armazenamento alocado elas podem reduzir alocações de memória e também tornar mais clara a intenção do seu código tornando-o mais legível.

E como identificamos uma variável de descarte ?

Você indica que uma variável é uma variável descartada, atribuindo a ela o sublinhado (_) como seu nome sendo que esta variável poderá receber qualquer tipo.

Dessa forma uma variável de descarte ( _ ) não aloca memória, sendo somente leitura e portanto não pode ter o seu valor obtido, visto que for descartado.

Você pode usar este recurso em um contexto que precisa descartar  um valor como em uma desconstrução, no retorno de valores de tuplas, com out ou onde você não quer guardar algum valor.

Por exemplo, a seguinte chamada de método retorna uma tupla de três valores em que o primeiro e o segundo valores são descartados e area é uma variável declarada anteriormente para ser definida como o terceiro componente correspondente retornado por GetInformacao():

 
    (_, _, area) = cidade.GetInformacao(nome);

 

Veja um exemplo de código onde apenas estamos descartando um valor:

    using static System.Console;
    class Program
    {
        static void Main(string[] args)
        {
            // Um exemplo simples usando uma variável de descarte
            _ = 1 + 2;
            // O código a seguir vai falhar
            //WriteLine("Tentendo obter uma variável discard : " + _);
        }
    }

Aqui se você descomentar o código para exibir o valor do descarte vai receber a mensagem de erro: "error CS0301, "The name '_' does not exist in the current context"

Um exemplo com desconstrução, que também é um novo recurso do C# 7.0, que permite dividir tuplas e outros objetos para valores individuais.

Neste contexto você pode não precisar de todos os valores retornados e é uma boa hora para usar o descarte :

        static void Main(string[] args)
        {
            var minhaTupla = (1, 1, 2, 3, 5, 8);

            (_, _, _, _, var cinco, _) = minhaTupla;

            WriteLine(cinco);
            ReadLine();
        }

Aqui estamos descartandos os valores 1, 2,3, e 8 e obtendo apenas o valor 5.

Agora muita atenção, pois se você tiver declarado uma variável _ ela vai ter a prioridade e vai receber o valor e ter a memória alocada:

Veja que aqui eu declarei uma variável _ do tipo int e a seguir estou tentando fazer o descarte mas o valor 4 já foi atribuído a variável _ e teve a memória alocada.

Agora vejamos o descarte com a correspondência de padrões ou  pattern matching.

Nota:  Os padrões ou Patterns foram introduzidos no C# 7.0 e a ideia é verificar se um objeto reflete uma forma especificada.

      private void ExemploPatternMatching()
        {
            object x = 13;
            if (x is var _)
            {
                // o código a seguir vai falhar
                // System.Console.WriteLine("Valor: " + _);
            }
        }

Com métodos que retornam valores via parâmetros out, podemos descartar o valor passando-o para o _.

Um exemplo de uso com o parâmetro out onde usamos o descarte para ignorar parâmetros:

   private void GetValores(out int primeiro, out int segundo, out int terceiro, out int quarto) =>
      primeiro = segundo = terceiro = quarto = 100;
   private void DemoDiscard()
   {
         GetValores(out _, out int ValorObtido, out _, out _);
   }

Veja mais detalhes na documentação oficial.

E estamos conversados...

"E se abrires a tua alma ao faminto, e fartares a alma aflita; então a tua luz nascerá nas trevas, e a tua escuridão será como o meio-dia."
Isaías 58:10

Referências:


José Carlos Macoratti