Click here to Skip to main content
11,641,659 members (60,400 online)
Click here to Skip to main content

Runtime C# Expression Evaluator

, 20 Apr 2002 Ms-PL 219.3K 3.5K 95
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

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 5 Pin
Renju Vinod9-May-13 2:14
professionalRenju Vinod9-May-13 2:14 
QuestionString Expression evaluation Pin
specialdreamsin13-Jun-12 23:27
memberspecialdreamsin13-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 code Pin
gonzalito_uy24-Apr-12 17:14
membergonzalito_uy24-Apr-12 17:14 
QuestionWhat about Double type ? Pin
Kronborn28-Mar-12 2:16
memberKronborn28-Mar-12 2:16 
GeneralMy vote of 5 Pin
MohammadAmiry3-Nov-11 1:30
memberMohammadAmiry3-Nov-11 1:30 
GeneralMy vote of 5 Pin
Nagy Vilmos2-May-11 0:18
memberNagy Vilmos2-May-11 0:18 
GeneralMy vote of 5 Pin
Yvan Rodrigues28-Mar-11 10:47
memberYvan Rodrigues28-Mar-11 10:47 
GeneralMy vote of 5 Pin
joyichantg21-Mar-11 20:30
memberjoyichantg21-Mar-11 20:30 
GeneralMy vote of 5 Pin
kaikg31-Aug-10 4:51
memberkaikg31-Aug-10 4:51 
GeneralGood job! Pin
kaikg31-Aug-10 4:51
memberkaikg31-Aug-10 4:51 
GeneralMy vote of 5 Pin
Igor Gresovnik16-Aug-10 11:58
memberIgor Gresovnik16-Aug-10 11:58 
GeneralThanks Pin
jigi_chavan13-Oct-09 1:02
memberjigi_chavan13-Oct-09 1:02 
Generalpls help Pin
Xandip30-Sep-09 4:50
memberXandip30-Sep-09 4:50 
Generalgreat tool! Pin
abomb2229-May-09 5:10
memberabomb2229-May-09 5:10 
RantDownload link is not working Pin
parslej27-Mar-09 4:58
memberparslej27-Mar-09 4:58 
GeneralBoolean expression evaluator Pin
jackietrillo17-Feb-09 17:22
memberjackietrillo17-Feb-09 17:22 
AnswerRe: Boolean expression evaluator Pin
Member 378665520-Feb-09 10:37
memberMember 378665520-Feb-09 10:37 
QuestionLicence ? Pin
asalmi16-Sep-08 6:12
memberasalmi16-Sep-08 6:12 
AnswerRe: Licence ? Pin
gonzalito_uy11-Feb-10 6:19
membergonzalito_uy11-Feb-10 6:19 
GeneralGarbage Collection Pin
TGKelley14-Aug-07 15:25
memberTGKelley14-Aug-07 15:25 
Questioncan a web project use "ReferencedAssemblies.Add("customer.dll")" Pin
wlbkeats7-Dec-06 23:34
memberwlbkeats7-Dec-06 23:34 
GeneralEval custom classes Pin
Pluisjeh15-Mar-06 0:41
memberPluisjeh15-Mar-06 0:41 
GeneralEval Objects Pin
ZiggY816-Mar-06 3:52
memberZiggY816-Mar-06 3:52 
GeneralIt's Great! Pin
James Yang20-Feb-06 3:16
memberJames Yang20-Feb-06 3:16 
GeneralGreat Article Pin
guruji3239-Nov-04 15:32
memberguruji3239-Nov-04 15:32 
GeneralPerformance penalty Pin
jelo_118-Jan-03 22:30
memberjelo_118-Jan-03 22:30 
Generalpassing arguments Pin
Ziv Rosenzweig24-Jul-02 5:26
sussZiv Rosenzweig24-Jul-02 5:26 
GeneralC# Parser Generator Pin
jhreich22-Jul-02 3:48
memberjhreich22-Jul-02 3:48 
GeneralRe: C# Parser Generator Pin
Anonymous23-Jul-02 17:33
sussAnonymous23-Jul-02 17:33 
GeneralRe: C# Parser Generator Pin
Jeff Varszegi25-Apr-04 20:29
memberJeff Varszegi25-Apr-04 20:29 
GeneralRe: C# Parser Generator Pin
Keith Rule11-Nov-05 6:35
memberKeith Rule11-Nov-05 6:35 
GeneralI like to know more... how to put the assembly into a SQL2000 Binary field... Pin
Chris Muench19-Jun-02 17:50
memberChris Muench19-Jun-02 17:50 
GeneralTotally amazing Pin
NielsH24-May-02 9:29
memberNielsH24-May-02 9:29 
GeneralGreat! Pin
Holger Persch22-Apr-02 20:02
memberHolger Persch22-Apr-02 20:02 
Generalseriously cool! Pin
ector22-Apr-02 4:56
memberector22-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 | Terms of Use | Mobile
Web01 | 2.8.150731.1 | Last Updated 21 Apr 2002
Article Copyright 2002 by Shawn Wildermuth
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid