lógica
Calculadora em C# sem usar comando condicional
3Fala Galera, hoje vamos construir uma calculadora sem utilizar comandos condicionais(IF,case..). Todos sabem como construir uma calculadora em C#, mas e se esta calculadora tivesse que ser construída sem utilizar comandos condicionais? O exemplo é legal para aprender algumas técnicas e um uso básico de delegates em C#. Vou mostrar um exemplo com comentários no código, e depois falo mais um pouco sobre o mais importante.
1:
2: namespace CalculadoraPT_BR
3: {
4:
5: //Delegate que será usado para todas as operações
6: delegate Decimal Operacao(Decimal val1, Decimal val2);
7: class Program
8: {
9: //Implementação das operações
10:
11: public static Decimal Somar(Decimal val1, Decimal val2)
12: {
13: return val1 + val2;
14: }
15: public static Decimal Subtrair(Decimal val1, Decimal val2)
16: {
17: return val1 - val2;
18: }
19: public static Decimal Dividir(Decimal val1, Decimal val2)
20: {
21: return val1 / val2;
22: }
23: public static Decimal Multiplicar(Decimal val1, Decimal val2)
24: {
25: return val1 * val2;
26: }
27:
28: static void Main(string[] args)
29: {
30: //Adicionando as funções na lista de Operacao
31: List<Operacao> operacoes = new List<Operacao>();
32: operacoes.Add(Somar);
33: operacoes.Add(Subtrair);
34: operacoes.Add(Dividir);
35: operacoes.Add(Multiplicar);
36:
37:
38: Console.WriteLine("Digite a opção desejada: 1-Somar,2-Subtrair,3-Dividir,4-Multiplicar");
39: var opc = Console.ReadLine();
40:
41: Console.WriteLine("Digite o primeiro Operando");
42: var op1 = Convert.ToInt32(Console.ReadLine());
43:
44: Console.WriteLine("Digite o segundo Operando");
45: var op2 = Convert.ToInt32(Console.ReadLine());
46:
47: //Identificando qual método executar através do indice e seleção do usuário
48: //OBS:**
49: var resultado = operacoes[Convert.ToInt32(opc) - 1](op1, op2);
50: Console.WriteLine("O resultado da operação é:" + resultado.ToString());
51:
52: Console.ReadKey();
53: }
54: }
55: }
Obs**
A técnica utiliza aqui se chama table-driven method. Basicamente colocamos o conhecimento do programa em uma estrutura de dados ao invés de colocarmos em instruções condicionais.Esta técnica pode ser muito útil em casos de grandes blocos IF-else, entretanto deve ser usada com cuidado para não complicar o código.Maiores informações sobre esta técnica podem ser encontradas no livro Code-Complete capitulo 18.Em breve farei um post sobre esta técnica.
Depois de um tempo vendo esta solução percebi que o C# me possibilita escrever o código de uma maneira mais elegante, vamos lá.
1: class Program
2: {
3:
4: static void Main(string[] args)
5: {
6: //Adicionando as funções na lista de Operacao
7: List<Func<Decimal, Decimal, Decimal>> operacoes = new List<Func<Decimal, Decimal, Decimal>>();
8: operacoes.Add((Decimal val1, Decimal val2) => { return val1 + val2; });
9: operacoes.Add((Decimal val1, Decimal val2) => { return val1 - val2; });
10: operacoes.Add((Decimal val1, Decimal val2) => { return val1 / val2; });
11: operacoes.Add((Decimal val1, Decimal val2) => { return val1 * val2; });
12:
13:
14: Console.WriteLine("Digite a opção desejada: 1-Somar,2-Subtrair,3-Dividir,4-Multiplicar");
15: var opc = Console.ReadLine();
16:
17: Console.WriteLine("Digite o primeiro Operando");
18: var op1 = Convert.ToInt32(Console.ReadLine());
19:
20: Console.WriteLine("Digite o segundo Operando");
21: var op2 = Convert.ToInt32(Console.ReadLine());
22:
23: //Identificando qual método executar através do indice e seleção do usuário
24: //OBS:**
25: var resultado = operacoes[Convert.ToInt32(opc) - 1](op1, op2);
26: Console.WriteLine("O resultado da operação é:" + resultado.ToString());
27:
28: Console.ReadKey();
29: }
30: }
O principal do post é a técnica de armazenar conhecimento dentro de uma estrutura de dados e eliminar condicionais. Abraços!
atualização: No exemplo usando lambda não é necessário declarar o tipo na hora de criar o método, exemplo:
1: operacoes.Add((a, b) => { return a + b; });
2: operacoes.Add((a, b) => { return a - b; });
3: operacoes.Add((a, b) => { return a * b; });
4: operacoes.Add((a, b) => { return a / b; });