Home   |  Articles   |  Resources   |  Humor   |  Feedback       

  Login   Register 

Ads Via DevMavens


An Eval Function for C# using JScript.NET (JavaScript)

Posted by on Saturday, January 03, 2004

Using the CodeDom you can compile just enough JScript (javascript) to use eval from C# without an extra assembly in the project.

Once I was faced with a scenario where we needed client specific calculations applied to the results of a SQL query. The situation cried out for a “eval” type method where we could just plug values into a custom equation and retrieve a result. VBScript, JScript.NET, and JavaScript all contain an eval method, where you can pass a string containing a valid expression for the language and retrieve a result – dynamic execution.

Unfortunately, C# does not provide an eval method. One solution is to add a JScript.NET project to your solution. It feels a bit messy to suddenly have an extra assembly to build and deploy just for 10 lines of JScript code. An alternate solution is to use the System.CodeDom namespace to compile a JScript class in memory to use.

The C# class below contains all static methods. Using the evaluator is as simple as:

Evaluator.EvalToInteger(“(9/6) + 3”);

Source code follows. To compile, make sure you add a reference to the Microsoft.JScript assembly. Most of the work in this class happens during the static constructor when we compile a small piece of JScript.NET code. Once we have the code compiled we can reach inside the assembly and create an instance of the evaluation class. Since a static constructor will execute only once – your application will only perform this work the first time execution references a static member of the class.

With an object instance in hand, we use InvokeMember to dynamically invoke the method to perform evaluation. Links in the resources section will provide more information.

Update: Be careful using dynamic execution. There is always the risk of a code injection attack, particularly if the input comes from an untrusted source.

 

using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.JScript;

namespace OdeToCode.Utility
{
   public class Evaluator
   {
      public static int EvalToInteger(string statement)
      {
         string s = EvalToString(statement);
         return int.Parse(s.ToString());
      }

      public static double EvalToDouble(string statement)
      {
         string s = EvalToString(statement);
         return double.Parse(s);
      }

      public static string EvalToString(string statement)
      {
         object o = EvalToObject(statement);
         return o.ToString();
      }

      public static object EvalToObject(string statement)
      {
         return _evaluatorType.InvokeMember(
                     "Eval", 
                     BindingFlags.InvokeMethod, 
                     null, 
                     _evaluator, 
                     new object[] { statement } 
                  );
      }
               
      static Evaluator()
      {
         ICodeCompiler compiler;
         compiler = new JScriptCodeProvider().CreateCompiler();

         CompilerParameters parameters;
         parameters = new CompilerParameters();
         parameters.GenerateInMemory = true;
         
         CompilerResults results;
         results = compiler.CompileAssemblyFromSource(parameters, _jscriptSource);

         Assembly assembly = results.CompiledAssembly;
         _evaluatorType = assembly.GetType("Evaluator.Evaluator");
         
         _evaluator = Activator.CreateInstance(_evaluatorType);
      }
      
      private static object _evaluator = null;
      private static Type _evaluatorType = null;
      private static readonly string _jscriptSource = 
         
          @"package Evaluator
            {
               class Evaluator
               {
                  public function Eval(expr : String) : String 
                  { 
                     return eval(expr); 
                  }
               }
            }";
   }
}

by K. Scott Allen

Resources

.NET Framework Developer’s Guide : Using the CodeDOM

HOWTO: Programmatically Compile Code Using C# Compiler

Dynamically Loading and Using Types


Comments:

compie command ?
By webber on 3/7/2004
is there an available batch file with the command code to compile this ?

Command line compile
By scott on 3/7/2004
Let's assume you copy the above code into a file called eval.cs. Also assume the command line compiler csc is in your path. Then to create an eval.dll do the following:

csc /r:Microsoft.Jscript.dll /t:library eval.cs

Nice !
By Krantz on 4/18/2004
Nice code !
But the example should be
Evaluator.EvalToDouble("(9/6) + 3");
no ?

how to evaluate this string
By satellite on 5/22/2004
how to evaluate this line of code below

"Dim submenu0 As New skmMenu.MenuItem('Home', '')"

Re: How to evaluate this line of code
By scott on 5/23/2004
Satellite:

This eval function is really built for evaluating expressions. The code snippet you have is a variable declaration and would not return a presentable "result". If you want to compile the code you could use the CodeDom similar to the article, however.

Question
By devitj on 10/14/2004
Does anyone know if C# supports Execute function as in VBScript?
Any response is appreciated.

How to evaluate this line
By ashaik on 1/12/2005
MyVar = "IIF(3=4, 5, IIF(4=5, 6, 7))"

If the result is boolean
By federico.caselli on 1/31/2005
I need to evaluate a boolean expression like

blnResult= Evaluator.EvalToBoolean("7>8")
MessageBox.Show(blnResult.ToString) '.... False

so I tried to add EvalToBoolean method to the Evaluator class:
------------------------------------------------
public static bool EvalToBoolean(string statement)
{
string s = EvalToString(statement);
return bool.Parse(s.ToString());
}
------------------------------------------------

but I get an exception. Is there some way to do this?



i can't get it to work
By used23 on 2/15/2005
TextBox1 contains my expression.
Some expressions I tried are:

("beth" > "abe") or ("tucan" = "sam")

and

(((1=1 or 3>2) and (2<>1)))

My code:

Dim evaluator1 As New OdeToCode.Utility.Evaluator
'return evaluator1.EvalToString(sInput)
'Return evaluator1.EvalToObject(sInput)
Return evaluator1.EvalToInteger(sInput)

none of these work.

Can someone help?

Thanks

Variable substitution
By RobZ on 2/24/2005
Hi There,
Is the following scenario possible?
var1 = "harry";
var2 = "23";
evaluate (var1 + " = " + var2);
(answer required : harry = 23)
? harry
> 23
Please Help!!

If the result is boolean
By karnala on 6/20/2005
any solution? please post any solution for this issue. i'm also facing the same problem. kindly help me

help me please
By karnala on 6/20/2005
I need to evaluate a boolean expression like

blnResult= Evaluator.EvalToBoolean("7>8")
MessageBox.Show(blnResult.ToString) '.... False

so I tried to add EvalToBoolean method to the Evaluator class:
------------------------------------------------
public static bool EvalToBoolean(string statement)
{
string s = EvalToString(statement);
return bool.Parse(s.ToString());
}
------------------------------------------------

but I get an exception. Is there some way to do this?

re: bool
By scott on 6/20/2005
Hi Karnala:

If I cut and paste your new method into the Evaluator class and use it from a Console application it appears to work just fine. What line is the exception occuring on? Feel free to email your code and perhaps I could help - I have a contact form on my blog.

Copyright 2004 OdeToCode.com 


The Blogs
Subscribe to the OdeToCode blogs for the latest news, downloads, new articles, and quirky commentary.
New Articles
Databinding in Silverlight
This article will cover data binding features in Silverlight, including binding expressions, validation, converters, and binding modes.

The Standard LINQ Operators
This article will cover the standard LINQ operators provided by LINQ for filtering, grouping, joining, converting, projecting, and more.

C# 3.0 and LINQ
C# 3.0 introduced a number of new features for LINQ. In this article we'll examine the new features like extension methods, lambda expressions, anonymous types, and more.

Most Popular Articles
Table Variables In T-SQL
Table variables allow you to store a resultset in SQL Server without the overhead of declaring and cleaning up a temporary table. In this article, we will highlight the features and advantages of the table variable data type.

ASP.Net 2.0 - Master Pages: Tips, Tricks, and Traps
MasterPages are a great addition to the ASP.NET 2.0 feature set, but are not without their quirks. This article will highlight the common problems developers face with master pages, and provide tips and tricks to use master pages to their fullest potential.

AppSettings In web.config
In this article we will review a couple of pratices to keep your runtime configuration information flexible.

Contribute Code
Privacy
Consultancy