BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Correspondência de padrões no C# 6 e no VB 12

Correspondência de padrões no C# 6 e no VB 12

Mais um conceito das linguagens de programação funcional está trilhando seu caminho para o C# e o VB. Conhecido como pattern matching (correspondência de padrões), à primeira vista se parece com um bloco switch/select, contudo este técnica é muito mais ampla e poderosa do que se imagina.

Nota: Como a versão da especificação em VB ainda não está disponível, muitos destes exemplos são da especificação de correspondência de padrões para C#.

O operador is ou Matches

No núcleo do suporte à correspondência de padrões no .NET está o operador "is/Matches". Este operador bastante incomum, quebra uma classe em suas partes constituintes. Aqui está um exemplo baseado na classe de registro Cartesiano, relatada neste artigo:

public static bool operator is(Cartesian c, out double x, out double y)
x = c.X;
y = c.Y;
return true;

Este operador não se limita apenas ao tipo proprietário. O próximo exemplo, mostra a definição do operador de uma forma em que ele permite decompor um objeto Cartesiano como se ele fosse um objeto Polar.

public static class Polar {
public static bool operator is( Cartesian c, out double R, out double Theta)
{
R = Math.Sqrt(c.X*c.X + c.Y*c.Y);
Theta = Math.Atan2(c.Y, c.X);
return c.X != 0 || c.Y != 0;
}
}
var c = Cartesian(3, 4);
if (c is Polar(var R, *))
Console.WriteLine(R);

Padrões de Tipos

O padrão mais simples é o padrão de tipo, que essencialmente é um try-cast com uma atribuição. Aqui está um exemplo:

if (expr is Type v)
{ // code using v }

Padrão Recursivo

A maioria dos padrões será recursiva. Ou seja, eles serão formados de outros padrões, frequentemente mais simples. Veja este exemplo:

var a = new Location(1, 2, 3); //x=1, y=2, z=3
if (a is Location(1, var y, *))

Este é um padrão recursivo que consiste de um padrão constante, um padrão var e um padrão de caracter coringa.

Padrão Constante

Ocorre quando uma correspondência é feita entre uma propriedade e um valor constante. Padrões constantes usam object.Equals(left, right) para avaliar se existe uma correspondência.

Padrão Var

O padrão var é sempre considerado uma correspondência. A variável associada é populada com o valor proveniente do operador is. O tipo desta variável é o tipo estaticamente definido da expressão.

Padrão de caracter coringa

O padrão de caracter coringa é essencialmente o padrão var, exceto que você não se interessa pelo resultado.

Como ele funciona

Continuando com nosso exemplo de localização, os passos que o compilador vai realizar serão semelhantes a:

  1. Criar variáveis $x, $y e $z
  2. Chamar Location.is(a, out $x, out $y, out $z) e verificar que ele retorna true
  3. Padrão contante: Verificar que object.Equals($x, 1)
  4. Padrão var: Definir y = $y
  5. Padrão de caracter coringa: Ignorar $z

Blocos Switch/Select Case

Blocos switch serão ampliados para utilizar correspondência de padrões. Essencialmente, isso significa que você pode escrever instruções como:

case null:
case String s
case Location(1, var y, *)

Limitações

No contexto do projeto de especificação atual, não há suporte para verificação de faixas de valores (ranges). Isso significa que você não pode escrever padrões como "a is Location( > 0, 1 to 5, <= 10)". Também não há suporte para correspondência de elementos em uma lista ou enumerador.

Considerações finais

O .NET framework já disponibiliza alguns aspectos de linguagens funcionais desde sua versão 3.0, mas esse conjunto de aspectos está sendo ampliado com essa nova especificação, ainda em desenvolvimento.

A introdução destas construções na linguagem poderá simplificar ainda mais a vida de programadores que pretendem escrever código em estilo funcional em uma linguagem imperativa como C#.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT