.NET

8 set, 2017

C# 7.0 – Pattern Matching

Publicidade

Ao manipular objetos cujas classes derivam de um mesmo tipo básico é extremamente comum se recorrer a checagens empregando o operador is. Também são frequentes operações de typecast indicando o uso de uma estrutura requerida por um contexto específico.

Para exemplificar isto serão utilizadas as seguintes classes:

  • Cotacao, tipo abstrato que representa uma cotação de moeda estrangeira;
  • CotacaoDolar, implementação concreta baseada em Cotacao e contendo informações da cotação do dólar norte-americano em uma data (tanto o valor comercial, quanto o correspondente para fins de turismo);
  • CotacaoEuro, com dados relativos a uma cotação do euro.

 

using System;
namespace ExemploPatternMatching
 {
 public abstract class Cotacao
 {
 public DateTime DataCotacao { get; set; }
 public abstract string SiglaMoeda { get; }
 public abstract string NomeMoeda { get; }
 }
public class CotacaoDolar : Cotacao
 {
 public override string SiglaMoeda
 { get { return "Dólar norte-americano"; } }
public override string NomeMoeda
 { get { return "USD"; } }
public double ValorComercial { get; set; }
 public double ValorTurismo { get; set; }
 }
public class CotacaoEuro : Cotacao
 {
 public override string SiglaMoeda
 { get { return "Euro"; } }
public override string NomeMoeda
 { get { return "EUR"; } }
public double ValorCotacao { get; set; }
 }
 }

Na próxima listagem está a definição de um método chamado ExibirInformacoesCotacao:

  • Esta operação receberá como parâmetro uma instância do tipo Cotacao, a fim de exibir informações sobre uma moeda estrangeira;
  • Um único valor de cotação será mostrado. Para referências baseadas em CotacaoEuro este dado se encontra na propriedade ValorCotacao. Já para o tipo CotacaoDolar será assumido o valor associado à propriedade ValorComercial. Até o C# 6.0 todo este processo acontecia empregando o operador is, além de incluir casts quando fosse necessário manipular implementações mais específicas da classe-base.

 

public static void ExibirInformacoesCotacao(Cotacao cotacao)
 {
 double valorCotacao = 0;
 if (cotacao is CotacaoDolar)
 {
 valorCotacao =
 ((CotacaoDolar)cotacao).ValorComercial;
 }
 else if (cotacao is CotacaoEuro)
 {
 valorCotacao =
 ((CotacaoEuro)cotacao).ValorCotacao;
 }
Console.WriteLine(new String('-', 40));
 Console.WriteLine(quot;Data: {cotacao.DataCotacao:dd/MM/yyyy}");
 Console.WriteLine(quot;Sigla: {cotacao.SiglaMoeda}");
 Console.WriteLine(quot;Moeda: {cotacao.NomeMoeda}");
 Console.WriteLine(quot;Valor: {valorCotacao:0.0000}");
 }

A seguir é possível observar um exemplo de uso do recurso de Pattern Matching (após a refatoração do método ExibirInformacoesCotacao):

  • Esta funcionalidade permite definir uma variável em conjunto com o operador is, com a mesma sendo preenchida caso a referência em análise corresponda ao tipo que se está verificando;
  • A vantagem deste novo mecanismo está em eliminar a necessidade de codificação de um typecast, contribuindo assim para um código mais limpo e direto.

 

using System;
namespace ExemploPatternMatching
 {
 class Program
 {
 public static void ExibirInformacoesCotacao(Cotacao cotacao)
 {
 double valorCotacao = 0;
 if (cotacao is CotacaoDolar dolar)
 valorCotacao = dolar.ValorComercial;
 else if (cotacao is CotacaoEuro euro)
 valorCotacao = euro.ValorCotacao;
Console.WriteLine(new String('-', 40));
 Console.WriteLine(quot;Data: {cotacao.DataCotacao:dd/MM/yyyy}");
 Console.WriteLine(quot;Sigla: {cotacao.SiglaMoeda}");
 Console.WriteLine(quot;Moeda: {cotacao.NomeMoeda}");
 Console.WriteLine(quot;Valor: {valorCotacao:0.0000}");
 }
static void Main(string[] args)
 {
 CotacaoDolar dolar = new CotacaoDolar();
 dolar.DataCotacao = new DateTime(2017, 3, 24);
 dolar.ValorComercial = 3.1083;
 dolar.ValorTurismo = 3.2700;
 ExibirInformacoesCotacao(dolar);
CotacaoEuro euro = new CotacaoEuro();
 euro.DataCotacao = new DateTime(2017, 3, 24);
 euro.ValorCotacao = 3.3695;
 ExibirInformacoesCotacao(euro);
Console.ReadKey();
 }
 }
 }

A execução deste bloco de código apresentará como resultado:

C# 7.0

O método ExibirInformacoesCotacao pode ainda ser refatorado, de forma a se fazer uso de um switch em conjunto com a funcionalidade de Pattern Matching:

public static void ExibirInformacoesCotacao(Cotacao cotacao)
 {
 double valorCotacao;
 switch (cotacao)
 {
 case CotacaoDolar dolar:
 valorCotacao = dolar.ValorComercial;
 break;
 case CotacaoEuro euro:
 valorCotacao = euro.ValorCotacao;
 break;
 default:
 valorCotacao = 0;
 break;
 }
Console.WriteLine(new String('-', 40));
 Console.WriteLine(quot;Data: {cotacao.DataCotacao:dd/MM/yyyy}");
 Console.WriteLine(quot;Sigla: {cotacao.SiglaMoeda}");
 Console.WriteLine(quot;Moeda: {cotacao.NomeMoeda}");
 Console.WriteLine(quot;Valor: {valorCotacao:0.0000}");
 }

Referências