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

Runtime C# Expression Evaluator

By , 20 Apr 2002
 
<!-- 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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Shawn Wildermuth

United States United States
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5professionalRenju Vinod9-May-13 2:14 
QuestionString Expression evaluationmemberspecialdreamsin13-Jun-12 23:27 
Hi All,

If you want to evaluate a string expression use the below code snippet.
using System.Data;
 
DataTable dt = new DataTable();
var v = dt.Compute("3 * (2+4)",""); 
 
Thanks & Regards,
Ramesh Sambari
(sambariramesh@gmail.com)
Knowledge is like honey.
Collect it, to make life sweet.

QuestionUsage of this codemembergonzalito_uy24-Apr-12 17:14 
QuestionWhat about Double type ?memberKronborn28-Mar-12 2:16 
GeneralMy vote of 5memberMohammadAmiry3-Nov-11 1:30 
GeneralMy vote of 5memberNagy Vilmos2-May-11 0:18 
GeneralMy vote of 5memberYvan Rodrigues28-Mar-11 10:47 
GeneralMy vote of 5memberjoyichantg21-Mar-11 20:30 
GeneralMy vote of 5memberkaikg31-Aug-10 4:51 
GeneralGood job!memberkaikg31-Aug-10 4:51 
GeneralMy vote of 5memberIgor Gresovnik16-Aug-10 11:58 
GeneralThanksmemberjigi_chavan13-Oct-09 1:02 
Generalpls helpmemberXandip30-Sep-09 4:50 
Generalgreat tool!memberabomb2229-May-09 5:10 
RantDownload link is not workingmemberparslej27-Mar-09 4:58 
GeneralBoolean expression evaluatormemberjackietrillo17-Feb-09 17:22 
AnswerRe: Boolean expression evaluatormemberMember 378665520-Feb-09 10:37 
QuestionLicence ?memberasalmi16-Sep-08 6:12 
AnswerRe: Licence ?membergonzalito_uy11-Feb-10 6:19 
Questiondoes it evaluate the expression ?memberParesh Gheewala7-Aug-08 21:21 
GeneralGarbage CollectionmemberTGKelley14-Aug-07 15:25 
Questioncan a web project use "ReferencedAssemblies.Add("customer.dll")"memberwlbkeats7-Dec-06 23:34 
GeneralEval custom classesmemberPluisjeh15-Mar-06 0:41 
GeneralEval ObjectsmemberZiggY816-Mar-06 3:52 
GeneralIt's Great!memberJames Yang20-Feb-06 3:16 

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130617.1 | Last Updated 21 Apr 2002
Article Copyright 2002 by Shawn Wildermuth
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid