Results 1 to 10 of 10

Thread: A simple way to evaluate mathematical expressions using CodeDom

  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.

  2. #2
    C# Aficionado Lord_Rat's Avatar
    Join Date
    Sep 2001
    Location
    Cave
    Posts
    2,497

    Re: A simple way to evaluate mathematical expressions using CodeDom

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

    Code:
    myCodeProvider.CompileAssemblyFromSource(cp,TempModuleSource);
    to

    Code:
    myCodeProvider.CreateCompiler().CompileAssemblyFromSource(cp,TempModuleSource);
    Need to re-register ASP.NET?
    C:\WINNT\Microsoft.NET\Framework\v#VERSIONNUMBER#\aspnet_regiis -i

    (Edit #VERSIONNUMBER# as needed - do a DIR if you don't know)

  3. #3

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

    Re: A simple way to evaluate mathematical expressions using CodeDom

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

    Bill
    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.

  4. #4
    New Member
    Join Date
    Jan 2007
    Posts
    2

    Re: A simple way to evaluate mathematical expressions using CodeDom

    Thanks Bill,
    as You said, clean and simple!

    // Magnus;

  5. #5
    New Member
    Join Date
    Apr 2007
    Posts
    3

    Re: A simple way to evaluate mathematical expressions using CodeDom

    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

  6. #6
    New Member
    Join Date
    Jan 2007
    Posts
    2

    Re: A simple way to evaluate mathematical expressions using CodeDom

    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;

  7. #7
    New Member
    Join Date
    Apr 2007
    Posts
    3

    Re: A simple way to evaluate mathematical expressions using CodeDom

    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?

  8. #8
    New Member
    Join Date
    Apr 2007
    Posts
    3

    Re: A simple way to evaluate mathematical expressions using CodeDom

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

  9. #9
    New Member
    Join Date
    Aug 2009
    Posts
    1

    Re: A simple way to evaluate mathematical expressions using CodeDom

    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

  10. #10
    New Member
    Join Date
    Dec 2009
    Posts
    1

    Re: A simple way to evaluate mathematical expressions using CodeDom

    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

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