Click here to Skip to main content
Click here to Skip to main content

Runtime C# Expression Evaluator

, 20 Apr 2002
Rate this:
Please Sign up or sign in to vote.
A C# class (and library if needed) to do runtime evaluations of C# expressions
<!-- Download Links --> <!-- Add the rest of your HTML here -->

Introduction

This is a simple class library (or just .cs file if you wish) to allow for runtime compilation and evaluation of C# code blocks. There are both static methods of the Evaluator class that allow for simple use (but at a performance penalty) or you can use the object directly to create multiple evaluations:

Console.WriteLine("Test0: {0}", Evaluator.EvaluateToInteger("(30 + 4) * 2"));
Console.WriteLine("Test1: {0}", Evaluator.EvaluateToString("\"Hello \" + \"There\""));
Console.WriteLine("Test2: {0}", Evaluator.EvaluateToBool("30 == 40"));
Console.WriteLine("Test3: {0}", Evaluator.EvaluateToObject("new DataSet()"));

EvaluatorItem[] items = {
                          new EvaluatorItem(typeof(int), "(30 + 4) * 2", "GetNumber"),
                          new EvaluatorItem(typeof(string), "\"Hello \" + \"There\"", 
                                                            "GetString"),
                          new EvaluatorItem(typeof(bool), "30 == 40", "GetBool"),
                          new EvaluatorItem(typeof(object), "new DataSet()", "GetDataSet")
                        };

Evaluator eval = new Evaluator(items);
Console.WriteLine("TestStatic0: {0}", eval.EvaluateInt("GetNumber"));
Console.WriteLine("TestStatic1: {0}", eval.EvaluateString("GetString"));
Console.WriteLine("TestStatic2: {0}", eval.EvaluateBool("GetBool"));
Console.WriteLine("TestStatic3: {0}", eval.Evaluate("GetDataSet"));

How does it work? I am using the CodeDOM to create a simple assembly with a single class in it. I simply transform each of the EvaluatorItems into a method of the class. When you call EvaluateInt() or Evaluate(), I use reflection to get a MethodInfo object and call the method.

The source code comes packaged in a Class Library with a Test program that you can use to get examples of use:

To compile the expressions, I am creating a new CSharpCodeProvider and setting Compiler attributes (like adding references, telling it to generate it in memory, etc.). Then I am building a dummy class that I can append my methods on. Lastly I compile it (check for errors) and save the object to use to call with the MethodInfo structure:

ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler());
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("system.data.dll");
cp.ReferencedAssemblies.Add("system.xml.dll");
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;

StringBuilder code = new StringBuilder();
code.Append("using System; \n");
code.Append("using System.Data; \n");
code.Append("using System.Data.SqlClient; \n");
code.Append("using System.Data.OleDb; \n");
code.Append("using System.Xml; \n");
code.Append("namespace ADOGuy { \n");
code.Append("  public class _Evaluator { \n");
foreach(EvaluatorItem item in items)
{
  code.AppendFormat("    public {0} {1}() ", 
                    item.ReturnType.Name, 
                    item.Name);
  code.Append("{ ");
  code.AppendFormat("      return ({0}); ", item.Expression);
  code.Append("}\n");
}
code.Append("} }");

CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
if (cr.Errors.HasErrors)
{
  StringBuilder error = new StringBuilder();
  error.Append("Error Compiling Expression: ");
  foreach (CompilerError err in cr.Errors)
  {
    error.AppendFormat("{0}\n", err.ErrorText);
  }
  throw new Exception("Error Compiling Expression: " + error.ToString());
}
Assembly a = cr.CompiledAssembly;
_Compiled = a.CreateInstance("ADOGuy._Evaluator");
    

When I call the _Compiled object, I use a MethodInfo object to Invoke the call and return the result to the user:

public object Evaluate(string name)
{
  MethodInfo mi = _Compiled.GetType().GetMethod(name);
  return mi.Invoke(_Compiled, null);
}
    

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Shawn Wildermuth

United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinprofessionalRenju Vinod9-May-13 2:14 
QuestionString Expression evaluation Pinmemberspecialdreamsin13-Jun-12 23:27 
QuestionUsage of this code Pinmembergonzalito_uy24-Apr-12 17:14 
QuestionWhat about Double type ? PinmemberKronborn28-Mar-12 2:16 
GeneralMy vote of 5 PinmemberMohammadAmiry3-Nov-11 1:30 
Excellent; thank you.
I just get the following obsolescence warning in .net 4:
 

 
Warning 1 'System.CodeDom.Compiler.CodeDomProvider.CreateCompiler()' is obsolete: 'Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class. Those inheriting from CodeDomProvider must still implement this interface, and should exclude this warning or also obsolete this method.' E:\My Projects\Evaluator\Evaluator.cs 35 29 Evaluator

GeneralMy vote of 5 PinmemberNagy Vilmos2-May-11 0:18 
GeneralMy vote of 5 PinmemberYvan Rodrigues28-Mar-11 10:47 
GeneralMy vote of 5 Pinmemberjoyichantg21-Mar-11 20:30 
GeneralMy vote of 5 Pinmemberkaikg31-Aug-10 4:51 
GeneralGood job! Pinmemberkaikg31-Aug-10 4:51 
GeneralMy vote of 5 PinmemberIgor Gresovnik16-Aug-10 11:58 
GeneralThanks Pinmemberjigi_chavan13-Oct-09 1:02 
Generalpls help PinmemberXandip30-Sep-09 4:50 
Generalgreat tool! Pinmemberabomb2229-May-09 5:10 
RantDownload link is not working Pinmemberparslej27-Mar-09 4:58 
GeneralBoolean expression evaluator Pinmemberjackietrillo17-Feb-09 17:22 
AnswerRe: Boolean expression evaluator PinmemberMember 378665520-Feb-09 10:37 
QuestionLicence ? Pinmemberasalmi16-Sep-08 6:12 
AnswerRe: Licence ? Pinmembergonzalito_uy11-Feb-10 6:19 
Questiondoes it evaluate the expression ? PinmemberParesh Gheewala7-Aug-08 21:21 
GeneralGarbage Collection PinmemberTGKelley14-Aug-07 15:25 
Questioncan a web project use "ReferencedAssemblies.Add("customer.dll")" Pinmemberwlbkeats7-Dec-06 23:34 
GeneralEval custom classes PinmemberPluisjeh15-Mar-06 0:41 
GeneralEval Objects PinmemberZiggY816-Mar-06 3:52 
GeneralIt's Great! PinmemberJames Yang20-Feb-06 3:16 
GeneralGreat Article Pinmemberguruji3239-Nov-04 15:32 
GeneralPerformance penalty Pinmemberjelo_118-Jan-03 22:30 
Generalpassing arguments PinsussZiv Rosenzweig24-Jul-02 5:26 
GeneralC# Parser Generator Pinmemberjhreich22-Jul-02 3:48 
GeneralRe: C# Parser Generator PinsussAnonymous23-Jul-02 17:33 
GeneralRe: C# Parser Generator PinmemberJeff Varszegi25-Apr-04 20:29 
GeneralRe: C# Parser Generator PinmemberKeith Rule11-Nov-05 6:35 
GeneralI like to know more... how to put the assembly into a SQL2000 Binary field... PinmemberChris Muench19-Jun-02 17:50 
GeneralTotally amazing PinmemberNielsH24-May-02 9:29 
GeneralGreat! PinmemberHolger Persch22-Apr-02 20:02 
Generalseriously cool! Pinmemberector22-Apr-02 4:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 21 Apr 2002
Article Copyright 2002 by Shawn Wildermuth
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid