lógica

Calculadora em C# sem usar comando condicional

3

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

Trabalhando com recursão em controles criados pelo usuário

0
Fala Galera, Agora mesmo estávamos discutindo aqui na empresa como usar recursão entre controles criados pelo usuário(Asp.Net – UserControl). O problema é o seguinte, temos um controle chamado profile, este controle possui vários campos de um simples cadastro(nome,endereço,E-mail,telefone e etc..).Temos a necessidade de colocar um controle de profile dentro de outro, é o caso que uma pessoa possui um conjugue. Então estávamos pensando como “chamar” um controle dentro do outro sem causar um loop infinito.Então chegamos a seguinte conclusão: No nosso controle profile criaremos uma propriedade HasConjugue(que é false como default) e criaremos um atributo para esta propriedade permitindo assim que ela seja setada como true quando necessário causando assim uma recursão. Então o funcionamento do controle ficou da seguinte maneira: no load do controle verificamos uma propriedade(hasconjugue) e se essa propriedade for verdadeira então carregamos outro controle, lembrando que como default é false nós só carregamos outro controle se na configuração de uso do profile(chamado) colocarmos a propriedade para verdadeiro.Sendo a propriedade verdadeira no primeiro load do controle a propriedade sera true então carregaremos um novo controle, Entretanto no novo controle carregado a propriedade estará false como default então um novo controle não será carregado. É isso galera, quem não entendeu pode entrar em contato ok? Até mais… Boa semana
Go to Top