# VBForums CodeBank > CodeBank - C# >  A simple way to evaluate mathematical expressions using CodeDom

## conipto

Ok, I searched around quite a bit for something that could do simple math expressions, and found a few complicated examples that utilised the CodeDom namespace in the .NET framework to let C# do all the work for us.  This function allows you to execute any C# code on the fly with slight modification, but for this purpose, it's primary function is as a calculator.  I put this up here because all of the examples I found were quite lengthy and typically contained alot more code than I needed for this simple task.  

To start, you need to either import the following namespaces, or fully qualify several of the variable declarations and method usages in the function.  I think it's much cleaner to just import the namespaces:


VB Code:
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;

Now that you have the namespaces imported into your project, the following function will solve almost all mathematical expressions (Basically anything you could solve in a single line of code)


VB Code:
/// <summary>
        /// A simple function to get the result of a C# expression (basic and advanced math possible)
        /// </summary>
        /// <param name="command">String value containing an expression that can evaluate to a double.</param>
        /// <returns>a Double value after evaluating the command string.</returns>
        private double ProcessCommand(string command)
        {
            //Create a C# Code Provider
            CSharpCodeProvider myCodeProvider = new CSharpCodeProvider();
            // Build the parameters for source compilation.
            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = false;//No need to make an EXE file here.
            cp.GenerateInMemory = true;   //But we do need one in memory.
            cp.OutputAssembly = "TempModule"; //This is not necessary, however, if used repeatedly, causes the CLR to not need to 
                                              //load a new assembly each time the function is run.
            //The below string is basically the shell of a C# program, that does nothing, but contains an
            //Evaluate() method for our purposes.  I realize this leaves the app open to injection attacks, 
            //But this is a simple demonstration.
            string TempModuleSource = "namespace ns{" +
                                      "using System;" +
                                      "class class1{" +
                                      "public static double Evaluate(){return " + command + ";}}} ";  //Our actual Expression evaluator
                                     
            CompilerResults cr = myCodeProvider.CompileAssemblyFromSource(cp,TempModuleSource);
            if (cr.Errors.Count > 0)
            {
                //If a compiler error is generated, we will throw an exception because 
                //the syntax was wrong - again, this is left up to the implementer to verify syntax before
                //calling the function.  The calling code could trap this in a try loop, and notify a user 
                //the command was not understood, for example.
                throw new ArgumentException("Expression cannot be evaluated, please use a valid C# expression");
            }
            else
            {
                MethodInfo Methinfo = cr.CompiledAssembly.GetType("ns.class1").GetMethod("Evaluate");
                return (double)Methinfo.Invoke(null, null);
            }
        }

It is a little on the slow side, but does work.  Any suggestions on how to speed up the process are encouraged.

Here are some sample calls to the function and their outputs:


VB Code:
Console.WriteLine(ProcessCommand("1+1").ToString()); //Displays 2
            Console.WriteLine(ProcessCommand("Math.PI").ToString()); //Displays 3.14159265358979
            Console.WriteLine(ProcessCommand("Math.Abs(-22)").ToString()); //Displays 22
            Console.WriteLine(ProcessCommand("3-4+6+7+22/3+66*(55)").ToString()); //Displays 3649

I will put a VB.NET version up later this week if anyone thinks it could be usefull.

Bill

----------


## Lord_Rat

For me to be able to use this, I had to change:



```
myCodeProvider.CompileAssemblyFromSource(cp,TempModuleSource);
```

to



```
myCodeProvider.CreateCompiler().CompileAssemblyFromSource(cp,TempModuleSource);
```

----------


## conipto

What version of C# are you using, out of curiousity?  The above was made with 2005.. 

Bill

----------


## MacMagnus

Thanks Bill, 
as You said, clean and simple!

// Magnus;

----------


## tuffc

I just stumble upon this, it is great.
Now when i run it on my local machine it works great, but when I put it on my server i get a Expression cannot be evaluated, please use a valid C# expression" error on any expression. Any idea how to fix that? 

and yes i realize this was posted a year ago

----------


## MacMagnus

probaly access rights...

This settings works for me with default settings on IIS on my server....

CSharpCodeProvider codeProvider = new CSharpCodeProvider();
CompilerParameters compilerParameters = new CompilerParameters();
compilerParameters.GenerateExecutable = false;
compilerParameters.GenerateInMemory = false;

string tmpModuleSource = "namespace ns{" + "using System;" + "class class1{" + "public static string Eval(double[] args){return \"Hello World\";}}} ";

CompilerResults compilerResults = codeProvider.CompileAssemblyFromSource(compilerParameters, tmpModuleSource);


// Magnus;

----------


## tuffc

Thanks for the response.

Everything in that code looks about the same except the false on generateinmemory. I tried that and no go, any other suggestions?

----------


## tuffc

I might want to add that I am using this as a web services using vs.net.

----------


## tmiles

I know the original post was submitted years ago, but wondering if there is a VB example at all.  I have tried to convert the code below to VB.NET 2008 but there is clearly something I am doing incorrectly and don't have the skills to fix.
Trevor

----------


## Ant2100

Hey Trevor,

I stumbled across this:
http://www.vbforums.com/showthread.php?t=397265

I think it may be what you need. It works perfectly in VB.NET 2008.

Anthony

----------

