Click here to Skip to main content
6,595,444 members and growing! (16,408 online)
Email Password   helpLost your password?
Languages » C# » General     Intermediate

Runtime C# Expression Evaluator

By Shawn Wildermuth

A C# class (and library if needed) to do runtime evaluations of C# expressions
C#, Windows, .NET 1.0, Dev
Posted:20 Apr 2002
Views:139,975
Bookmarked:65 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
71 votes for this article.
Popularity: 7.97 Rating: 4.30 out of 5
8 votes, 13.6%
1
1 vote, 1.7%
2

3
9 votes, 15.3%
4
41 votes, 69.5%
5

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


Member

Location: United States United States

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 24 of 24 (Total in Forum: 24) (Refresh)FirstPrevNext
GeneralThanks Pinmemberjigi_chavan2:02 13 Oct '09  
Generalpls help PinmemberXandip5:50 30 Sep '09  
Generalgreat tool! Pinmemberabomb226:10 29 May '09  
RantDownload link is not working Pinmemberparslej5:58 27 Mar '09  
GeneralBoolean expression evaluator Pinmemberjackietrillo18:22 17 Feb '09  
AnswerRe: Boolean expression evaluator PinmemberMember 378665511:37 20 Feb '09  
GeneralLicence ? Pinmemberasalmi7:12 16 Sep '08  
Generaldoes it evaluate the expression ? PinmemberParesh Gheewala22:21 7 Aug '08  
GeneralGarbage Collection PinmemberTGKelley16:25 14 Aug '07  
Generalcan a web project use "ReferencedAssemblies.Add("customer.dll")" Pinmemberwlbkeats0:34 8 Dec '06  
GeneralEval custom classes PinmemberPluisjeh1:41 15 Mar '06  
GeneralEval Objects PinmemberZiggY814:52 6 Mar '06  
GeneralIt's Great! PinmemberJames Yang4:16 20 Feb '06  
GeneralGreat Article Pinmemberguruji32316:32 9 Nov '04  
GeneralPerformance penalty Pinmemberjelo_123:30 18 Jan '03  
Generalpassing arguments PinsussZiv Rosenzweig6:26 24 Jul '02  
GeneralC# Parser Generator Pinmemberjhreich4:48 22 Jul '02  
GeneralRe: C# Parser Generator PinsussAnonymous18:33 23 Jul '02  
GeneralRe: C# Parser Generator PinmemberJeff Varszegi21:29 25 Apr '04  
GeneralRe: C# Parser Generator PinmemberKeith Rule7:35 11 Nov '05  
GeneralI like to know more... how to put the assembly into a SQL2000 Binary field... PinmemberChris Muench18:50 19 Jun '02  
GeneralTotally amazing PinmemberNielsH10:29 24 May '02  
GeneralGreat! PinmemberHolger Persch21:02 22 Apr '02  
Generalseriously cool! Pinmemberector5:56 22 Apr '02  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 20 Apr 2002
Editor: Chris Maunder
Copyright 2002 by Shawn Wildermuth
Everything else Copyright © CodeProject, 1999-2009
Web19 | Advertise on the Code Project