Evaluating an expression at runtime

I have a C # console application project.

I have a boolean expression that is stored in the database as nvarchar.

For example, a stored expression: ((34> 0) || (US == ES)) && & (4312 = 5691)

While my application is running, I want to get an expression and evaluate it so that the result is right or false.

How can I do this at runtime?

+4
source share
3 answers

Here's a rather unusual solution involving JScript:

  • Create a JScript class with the following code:

    public class JsMath { public static function Eval(expression:String) : Object { return eval(expression); } } 
  • Compile it in a DLL:

     jsc /target:library /out:JsMath.dll JsMath.js 
  • In your C # project, the JsMath.dll and Microsoft.JScript.dll link

  • Now you can use the Eval method as follows:

     string expression = "((34 > 0) || ('US' == 'ES')) && (4312 == 5691)"; bool result = (bool)JsMath.Eval(expression); 

Benefits:

  • no need to parse the expression, the JScript engine does this for you
  • No need to compile arbitrary code (which can be a big security hole if the code is entered by the user)
  • should work with any simple mathematical or logical expression if it follows JScript syntax

Disadvantages:

  • Unable to pass variables (as far as I know)
  • requires a reference to the JScript assembly (in most cases this is not a big problem, but I'm not sure if this assembly is available in the client profile or in Silverlight).
+7
source

You can parse the expression in the .NET Expression class and compile it and run to get the result.

The class already supports all the logical operations that you have in your example, although it seems ambiguous (you use both == and = very similar way).

You will have to write your own parser / converter.

+3
source

From here I wrote a more compact and efficient version of JScript C. Scott Allen's built-in Eval caller ( https://odetocode.com/articles/80.aspx ):

 using System; using System.CodeDom.Compiler; using Microsoft.JScript; class JS { private delegate object EvalDelegate(String expr); private static EvalDelegate moEvalDelegate = null; public static object Eval(string expr) { return moEvalDelegate(expr); } public static T Eval<T>(string expr) { return (T)Eval(expr); } public static void Prepare() { } static JS() { const string csJScriptSource = @"package _{ class _{ static function __(e) : Object { return eval(e); }}}"; var loParameters = new CompilerParameters() { GenerateInMemory = true }; var loMethod = (new JScriptCodeProvider()).CompileAssemblyFromSource(loParameters, csJScriptSource).CompiledAssembly.GetType("_._").GetMethod("__"); moEvalDelegate = (EvalDelegate)Delegate.CreateDelegate(typeof(EvalDelegate), loMethod); } } 

Just use it like this:

 JS.Eval<Double>("1 + 4 + 5 / 99"); 

Returns:

5.05050505050505

You can expand it to pass the values โ€‹โ€‹of variables, if you want, for example, pass it to the dictionary of names & values. The first use of the static class will take 100-200 ms, after which it is largely instantaneous and does not require a separate DLL. Call JS.Prepare () to precompile to stop the initial delay if you want.

0
source

All Articles