Olá novamente!
Hoje recebi um email de um colega, através de uma lista de discussão de dot.net, com uma dúvida sobre a otimização de switchs. Lembrei então de já ter visto um código em C que utilizava ponteiros de funções ao invés de switchs.
Resolvi então implementar uma solução similar em C# utilizando delegates no lugar dos ponteiros de funções. O código implementa as quatro operações aritméticas básicas dados dois números reais.
Para isso, foi definida a classe Calculadora com os métodos referentes as quatro operações. Além desses métodos foram definidos outros dois, o ExecutaComSwitch, que e executa uma operação realizando um teste com switch e o ExecutaComDelegate, que recebe um delegate com a operação a ser executada.
O programa principal recebe os valores de duas variáveis reais e em seguida executa as quatro operações utilizando o método com switch e o método com delegate.
O código da aplicação (console) é o seguinte:
using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace Switch{ public enum TipoOperacao { Soma, Subtracao, Multiplicacao, Divisao};
public delegate double OperacaoDelegate(double a, double b);
public class Calculadora { public double Soma(double a, double b) { return a + b; }
public double Substracao(double a, double b) { return a – b; }
public double Multiplicacao(double a, double b) { return a * b; }
public double Divisao(double a, double b) { return a / b; }
public double ExecutaComSwitch(TipoOperacao op, double a, double b) { double resultado = 0; switch (op) { case TipoOperacao.Soma: resultado = this.Soma(a, b); break; case TipoOperacao.Subtracao: resultado = this.Substracao(a, b); break; case TipoOperacao.Multiplicacao: resultado = this.Multiplicacao(a, b); break; case TipoOperacao.Divisao: resultado = this.Divisao(a, b); break; } return resultado; }
public double ExecutaComDelegate(OperacaoDelegate op, double a, double b) { return op(a, b); } }
class Program { static void Main(string[] args) { double a, b; Calculadora calc = new Calculadora(); Console.Clear(); Console.WriteLine(“Informe o valor de A:”); double.TryParse(Console.ReadLine(), out a); Console.WriteLine(“Informe o valor de B:”); double.TryParse(Console.ReadLine(), out b); Console.WriteLine();
Console.WriteLine(“Usando switch:”); double soma = calc.ExecutaComSwitch(TipoOperacao.Soma, a, b); Console.WriteLine(“Soma: {0}”, soma.ToString(“#,##0.00”)); double subtracao = calc.ExecutaComSwitch(TipoOperacao.Subtracao, a, b); Console.WriteLine(“Subtração: {0}”, subtracao.ToString(“#,##0.00”)); double multiplicacao = calc.ExecutaComSwitch(TipoOperacao.Multiplicacao, a, b); Console.WriteLine(“Multiplicação: {0}”, multiplicacao.ToString(“#,##0.00”)); double divisao = calc.ExecutaComSwitch(TipoOperacao.Divisao, a, b); Console.WriteLine(“Divisão: {0}”, divisao.ToString(“#,##0.00”)); Console.WriteLine();
Console.WriteLine(“Usando delegate:”); soma = calc.ExecutaComDelegate(calc.Soma, a, b); Console.WriteLine(“Soma: {0}”, soma.ToString(“#,##0.00”)); soma = calc.ExecutaComDelegate(calc.Substracao, a, b); Console.WriteLine(“Subtração: {0}”, subtracao.ToString(“#,##0.00”)); soma = calc.ExecutaComDelegate(calc.Multiplicacao, a, b); Console.WriteLine(“Multiplicação: {0}”, multiplicacao.ToString(“#,##0.00”)); soma = calc.ExecutaComDelegate(calc.Divisao, a, b); Console.WriteLine(“Divisão: {0}”, divisao.ToString(“#,##0.00”));
Console.ReadLine(); } }}