Results 1 to 10 of 10

Thread: A simple way to evaluate mathematical expressions using CodeDom

Threaded View

  1. #1

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    A simple way to evaluate mathematical expressions using CodeDom

    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:
    1. using System.CodeDom.Compiler;
    2. using Microsoft.CSharp;
    3. 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:
    1. /// <summary>
    2.         /// A simple function to get the result of a C# expression (basic and advanced math possible)
    3.         /// </summary>
    4.         /// <param name="command">String value containing an expression that can evaluate to a double.</param>
    5.         /// <returns>a Double value after evaluating the command string.</returns>
    6.         private double ProcessCommand(string command)
    7.         {
    8.             //Create a C# Code Provider
    9.             CSharpCodeProvider myCodeProvider = new CSharpCodeProvider();
    10.             // Build the parameters for source compilation.
    11.             CompilerParameters cp = new CompilerParameters();
    12.             cp.GenerateExecutable = false;//No need to make an EXE file here.
    13.             cp.GenerateInMemory = true;   //But we do need one in memory.
    14.             cp.OutputAssembly = "TempModule"; //This is not necessary, however, if used repeatedly, causes the CLR to not need to
    15.                                               //load a new assembly each time the function is run.
    16.             //The below string is basically the shell of a C# program, that does nothing, but contains an
    17.             //Evaluate() method for our purposes.  I realize this leaves the app open to injection attacks,
    18.             //But this is a simple demonstration.
    19.             string TempModuleSource = "namespace ns{" +
    20.                                       "using System;" +
    21.                                       "class class1{" +
    22.                                       "public static double Evaluate(){return " + command + ";}}} ";  //Our actual Expression evaluator
    23.                                      
    24.             CompilerResults cr = myCodeProvider.CompileAssemblyFromSource(cp,TempModuleSource);
    25.             if (cr.Errors.Count > 0)
    26.             {
    27.                 //If a compiler error is generated, we will throw an exception because
    28.                 //the syntax was wrong - again, this is left up to the implementer to verify syntax before
    29.                 //calling the function.  The calling code could trap this in a try loop, and notify a user
    30.                 //the command was not understood, for example.
    31.                 throw new ArgumentException("Expression cannot be evaluated, please use a valid C# expression");
    32.             }
    33.             else
    34.             {
    35.                 MethodInfo Methinfo = cr.CompiledAssembly.GetType("ns.class1").GetMethod("Evaluate");
    36.                 return (double)Methinfo.Invoke(null, null);
    37.             }
    38.         }

    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:
    1. Console.WriteLine(ProcessCommand("1+1").ToString()); //Displays 2
    2.             Console.WriteLine(ProcessCommand("Math.PI").ToString()); //Displays 3.14159265358979
    3.             Console.WriteLine(ProcessCommand("Math.Abs(-22)").ToString()); //Displays 22
    4.             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
    Last edited by conipto; Apr 5th, 2006 at 12:37 AM. Reason: Removed unneccessary void Main()
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width