Switch vs. Delegate

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();
}
}
}

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();        }    }}

 

Leave a comment