BT

A sua opinião é importante! Por favor preencha a pesquisa do InfoQ!

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

| por Jonathan Allen Seguir 198 Seguidores , traduzido por Roberto Pepato Seguir 9 Seguidores em 22 ago 2014. Tempo estimado de leitura: 3 minutos |

Para melhorar a experiência das pessoas que acessam o InfoQ Brasil, nós criamos uma série de funcionalidades que te permitem ficar pode dentro das últimas tendências e das novidades de seu interesse, sem que você seja incomodado por coisas irrelevantes. Receba e-mails periódicos e notificações sobre seus tópicos favoritos!

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

Olá visitante

Você precisa cadastrar-se no InfoQ Brasil ou para enviar comentários. Há muitas vantagens em se cadastrar.

Obtenha o máximo da experiência do InfoQ Brasil.

Dê sua opinião

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão
Comentários da comunidade

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão

Dê sua opinião

Faça seu login para melhorar sua experiência com o InfoQ e ter acesso a funcionalidades exclusivas


Esqueci minha senha

Follow

Siga seus tópicos e editores favoritos

Acompanhe e seja notificados sobre as mais importantes novidades do mundo do desenvolvimento de software.

Like

Mais interação, mais personalização

Crie seu próprio feed de novidades escolhendo os tópicos e pessoas que você gostaria de acompanhar.

Notifications

Fique por dentro das novidades!

Configure as notificações e acompanhe as novidades relacionada a tópicos, conteúdos e pessoas de seu interesse

BT