C# - Usando Pattern Matching 
 Hoje vamos recordar o conceito de Pattern Matching e mostrar algumas possibilidades de uso.

O termo Pattern Matching ou correspondência de padrões, é o ato de verificar se existe uma sequência específica de caracteres/tokens/dados entre os dados fornecidos, sendo também usado para localizar e substituir um padrão correspondente em um texto ou código por outro texto/código.

Em contraste com o reconhecimento de padrões, a correspondência geralmente precisa ser exata: "ou será ou não será uma correspondência".

Este recurso foi introduzido com o C# 7.0 e permite escrever código mais limpo e conciso em muitos cenários diferentes.

Você não precisa usar o recurso Pattern Matching mas ele pode transformar uma instrução complexa if-else ou switch em um bloco compacto de código, sendo que seu ponto forte é que ele é expressivo, tornando o código mais fácil de ler e mais difícil de escrever bugs.

Um bônus é que o compilador atua como uma rede de segurança avisando sobre casos não tratados e evita que os casos entrem em conflito entre si. Isso não é algo que você obtém com uma declaração normal if-else, e assim é bom saber que o compilador vai te apoiar alertando para erros bobos.

A seguir vamos dar uma olhada em alguns exemplos de como a correspondência de padrões com expressões switch é usada.

Em todos os exemplos estou usando uma aplicação Console (.NET Core) criada no ambiente do .NET 6 usando C# 10.

Exemplos de uso de Pattern Matching

 Vamos iniciar um exemplo mais simples possível onde temos uma verificação de um valor verdadeiro/falso.

A correspondência de padrões compara um valor de entrada (falso no exemplo abaixo) a um conjunto de padrões definidos, pense neles como um conjunto de condições. Os padrões dentro da expressão switch são avaliados de cima para baixo e o primeiro caso que causa uma correspondência é executado.

2- Padrões Constantes

Podemos usar a correspondência de padrões para verificar se uma variável tem um valor constante. Os tipos que podem ser correspondidos são strings, caracteres, números e enumerações.

Neste código temos o seguinte alerta do compilador:   warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '0' is not covered.

Isso ocorre porque nem todo o número está incluído na expressão switch do exemplo. Para resolver esse alerta, podemos adicionar um caso de fallback.  Pense nisso como um caso padrão de uma instrução switch, um curinga que é invocado quando nenhum outro dos padrões anteriores é correspondido.

No exemplo a seguir, o operador de descarte (representado como um sublinhado _) é usado para corresponder a todos os outros valores possíveis.

3- Padrões variáveis

Um valor correspondente pode ser atribuído a uma variável.

No exemplo a seguir, a variável atua como um curinga que corresponde a qualquer valor. Uma variável também pode ser definida quando o valor de entrada de um Type Pattern corresponde a um Type, a variável criada é digitada neste caso. A variável pode então ser usada na expressão de execução (após o =>) para criar um valor de retorno.

Além disso, uma instrução when pode ser adicionada ao padrão para adicionar uma proteção extra ao padrão. A instrução when pode ser usada para corresponder um valor não constante a uma condição, por exemplo, para invocar um método na variável correspondente. Além de corresponder ao objeto que está sendo correspondido, também é possível incluir outros objetos na instrução when.

4 -  Padrões Relacionais

Podemos usar o operadores de relação (=, >, <, >=, <=) para testar se a entrada é igual, maior ou menor que outro valor:

Observe que cometemos um engano de propósito no código acima.  Você identificou o erro no exemplo?

Se não for esse o caso, você não precisa se preocupar, porque o compilador lança um alerta para indicar o meu erro :
erro CS8510: O padrão está inacessível. Já foi tratado por um braço anterior da expressão switch ou é impossível corresponder.

Vamos corrigir esse erro corrigindo o padrão.

5- Vários padrões

Para combinar padrões ou negar valores, usamos os operadores lógicos (and, or, not).

6 - Padrões de Tupla

Corresponder a valores únicos é bom, mas não é muito útil em muitos casos. Para corresponder a vários valores, podemos combinar vários valores de entrada usando tuplas.

Nota: Uma tupla é uma estrutura de dados que tem um número específico e sequencial de elementos.

7- Padrões de propriedade

Quando a entrada é um objeto, podemos adicionar um padrão às propriedades do objeto.

8 - Padrões de propriedades aninhadas

Podemos também combinar propriedades aninhadas.

O exemplo acima pode ser difícil de ler (especialmente se você precisar detalhar vários objetos).

Como solução, o C# 10 fornece uma nova sintaxe chamada padrões de propriedade estendidos para tornar isso mais fácil de entender. O exemplo refatorado tem a seguinte aparência :

Melhorou um pouco !!!

Vimos assim alguns exemplos de expressões de correspondência de padrões. Para mais detalhes, consulte a documentação oficial:

E estamos conversados.

Pegue o código aqui: CShap_PatternMatch.zip

"Aguardo ansiosamente e espero que em nada serei envergonhado. Pelo contrário, com toda a determinação de sempre, também agora Cristo será engrandecido em meu corpo, quer pela vida quer pela morte;
porque para mim o viver é Cristo e o morrer é lucro "
Filipenses 1:20-21

Referências:


José Carlos Macoratti