Usando o Pattern Matching do C#
C#
Olá pessoa!
Antes de qualquer coisa, sim, semana passada publiquei um post sobre a criação de uma nova alternativa para o pattern matching do C# (já tenho um experimento melhor, logo devo publicar por aqui) e para minha surpresa, boa parte dos leitores não conheciam essa feature. Então, vamos falar um pouquinho dela por aqui!
Primeiro é justo começar falando que o pattern matching do C# não tem o mesmo poder que o do F#, nem mesmo funciona em todas as situações, mas é uma feature bastante útil e você pode estar passando trabalho à toa.
Como você deve ter visto no post passado, o pattern matching do C# geralmente se comporta da seguinte maneira: utilizamos a palavra reservada is
para checar alguma condição e depois disso declaramos uma variável para receber o resultado, caso a condição seja atendida.
Considere a variável valor
com o número 10 armazenado nela, a partir disso, vamos montar alguns exemplos:
if(valor is null)
{
//Fazendo vários nadas
}
Neste exemplo, a variável simplesmente está sendo comparada com null
, semelhante à um valor == null
.
const int TRES = 3;
if(valor is TRES)
{
//Fazendo vários nadas
}
Este segundo exemplo é bastante semelhante ao anterior, simplesmente estamos comparando a variável com outro valor, mas neste caso, com uma constante.
Vamos complicar um pouquinho mais:
if(valor is int numero)
{
//Fazendo vários nadas
}
Neste caso, estamos checando se o valor é um inteiro. Além disso, caso o valor seja um inteiro é feito um cast e a variável numero recebe 10 (dado armazenado na variável valor).
Um ponto importante é que só conseguiremos acessar o valor de numero
dentro do escopo do if
. Afinal, ele só receberá o valor quando a condição for atendida.
Outro ponto é que caso você precise de mais uma comparação você não poderá utilizar o mesmo nome de variável porque o compilador irá reclamar:
if(valor is int numero)
{
//Fazendo vários nadas
}
if(valor is double numero2 )
{
//Fazendo outros nadas
}
Também podemos utilizar o pattern matching para turbinar o nosso switch-case
. Confesso que eu tendo a não gostar desse comando, mas com pattern matching ele fica “menos feio”. Podemos utilizar um switch para checagem de tipo, considere que você tem um tipo genérico e deseja tomar decisões diferentes de acordo com o tipo específico:
public string NomeColecao<T>(IEnumerable<T> colecao)
{
switch (colecao)
{
case Array array: return "Array";
case List<T> lista: return "Lista";
case ICollection collection: return "Coleção genérica";
default: return "Coleção secreta";
}
}
Neste caso, nosso switch
recebe uma coleção genérica do tipo IEnumerable
e retorna o nome da coleçao de acordo com a checagem de tipos.
Por fim, podemos turbinar ainda mais nosso switch
utilizando a palavra reservada when
. Com ela é possível finalmente colocar uma condição dentro de uma cláusula case
:
public string SwitchCaseCondicional(int valor)
{
switch (valor)
{
case int numero when numero % 2 == 0:
return "Par";
case int numero when numero > 100:
return "Número maior que Cem";
case int numero when numero > 10 && numero < 50:
return "Número entre 10 e 50";
case int numero when numero % 2 == 1:
return "Número Ímpar";
default: return "Número secreto";
}
}
É importante lembrar que a ordem dos casos importa, assim como no switch
normal.
Por último, vale lembrar que você também pode utilizar tuplas para condições no switch
, mas para isso, declaramos o tipo var
, conforme código:
(int numero, string texto) valores = (10, "teste");
switch (valores)
{
case var tupla when valores.numero == 0:
//Fazendo vários nadas
break;
case var tupla when string.IsNullOrEmpty(valores.texto):
//Fazendo outros nadas
break;
}
Bom, por hoje é isso!
O que achou?
Alguma sugestão? Gostou deste tipo de post?
Me conte nos comentários!
E Até mais!
Sempre vale lembrar que as informações e textos aqui no blog representam minha opinião pessoal, o que pode não ser igual à sua ou de qualquer outra pessoa, incluindo a empresa para qual eu trabalho. Portanto as publicações inseridas aqui estão relacionadas somente a mim.