C# - Avaliando Expressões Matemáticas
Como avaliar expressões matemáticas ???
Usando o namespace CodeDom do .NET Framework podemos contornar esse problema.
O namespace System.CodeDom fornece classes para representar a estrutura lógica do código-fonte, independente da sintaxe da linguagem.
As classes existentes no namespace CodeDOM retratam elementos sintáticos e comandos, também conhecidos com Tokens, existentes em um código fonte escrito em qualquer linguagem .Net. Todo e qualquer token existente na sintaxe da Intermediate language(IL), gerada pelos compiladores das linguagens que usualmente trabalhamos(C#, VB, etc), possui uma classe que o representa no CodeDOM.
Por exemplo, existem classes que representam declarações de namespaces, criação de tipos, definição de estruturas, ifs, fors, atribuições de variáveis, chamadas de métodos e quaisquer comandos que podemos codificar quando utilizamos .NET.
A classe abstrata CodeDomProvider tem um papel essencial na arquitetura descrita acima, pois ela define como deve ser o comportamento padrão para as demais linguagens existentes na plataforma .Net. (http://msdn.microsoft.com/pt-br/library/cc517997.aspx)
Alguns usos comuns do CodeDOM incluem:
No exemplo deste artigo temos uma aplicação feita na linguagem C# que mostra como avaliar expressões matemáticas simples.
Abra o Visual C# 2010 Express Edition e crie um novo projeto Windows Forms Application com o nome AvaliacaoMatematica;
Abaixo o formulário da aplicação avaliando uma expressão matemática, calculando e exibindo o resultado em controles TextBox:
A seguir o código do formulário:
sing System; using System.Windows.Forms; using System.CodeDom.Compiler; using Microsoft.CSharp; using System.Reflection; namespace AvaliacaoMatematica { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private double ProcessarCommando(string command) { //Cria um provedor de Código C# CSharpCodeProvider mCodeProvider = new CSharpCodeProvider(); // Cria os parmaetros para a compilação origem CompilerParameters cp = new CompilerParameters(); cp.GenerateExecutable = false; //Não precisa criar um arquivo EXE cp.GenerateInMemory = true; //Cria um na memória cp.OutputAssembly = "TempModule"; // Isso não é necessário, no entanto, se usado repetidamente, faz com que o CLR //não precisa carregar uma novo assembly cada vez que a função é executada. // A string abaixo é basicamente a casca do programa C #, que não faz nada, mas contém um método Avaliar() // para nossos propósitos. //Atenção: Isso deixa a aplicação app aberto a ataques de injeção, //Estou fazendo apenas para demonstração . string TempModuleSource = "namespace ns{" + "using System;" + "class class1{" + "public static double Evaluate(){return " + command + ";}}} "; //Calcula a expressão CompilerResults cr = mCodeProvider.CompileAssemblyFromSource(cp, TempModuleSource); if (cr.Errors.Count > 0) { //Se um erro de compilação é gerado, iremoslançar uma exceção //A sintaxe estava errado - novamente, isso é deixado ao implementador para verificar sintaxe antes //Chamando a função. O código de chamada pode prender isso em um laço try, e notificar o usuário //O comando não foi compreendido, por exemplo. throw new ArgumentException("A expressão não pode ser avaliada, utiliza uma expressão C# válida..."); } else { MethodInfo Methinfo = cr.CompiledAssembly.GetType("ns.class1").GetMethod("Evaluate"); return (double)Methinfo.Invoke(null, null); } } private void button1_Click(object sender, EventArgs e) { try { txtResultado.Text = ProcessarCommando(txtOperacao.Text).ToString(); } catch (Exception ex) { MessageBox.Show("Erro a avaliar a expressão..." + ex.Message.ToString() + " Obrigado..."); } //Exemplos //ProcessCommand("Math.PI").ToString()); //Exibe 3.14159265358979 //ProcessCommand("Math.Abs(-22)").ToString()); //Exibe 22 //ProcessCommand("3-4+6+7+22/3+66*(55)").ToString()); //Exibe 3649 } } } |
A classe CSharpCodeProvider fornece acesso a instâncias do gerador de código C# e do compilador de código.
A classe CompilerResults representa o resultado da compilação que é retornado a partir do compilador.
Essa classe contém informações sobre os resultados de uma compilação de uma implementação de interface ICodeCompiler:
Pegue o projeto completo aqui: AvaliacaoMatematica.zip (Abra no Visual C# 2010 Express ou superior.)
Eclesiastes 12:1
Lembra-te também do teu Criador nos dias da tua mocidade, antes que venham os maus dias, e cheguem os anos em que dirás: Não tenho prazer neles;Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
VB .NET - Resolvendo equações do segundo grau - Macoratti.net
http://msdn.microsoft.com/pt-br/library/microsoft.csharp.csharpcodeprovider.aspx