Reputation: 4039
I have a C# Console Application project.
I have a logical expression that is stored in database as nvarchar.
For example, the stored expression is: ((34 > 0) || (US == ES)) && (4312 = 5691)
While my application running, I want to retrieve the expression and evaluate it so that the result will be true or false.
How can I do it at runtime?
Upvotes: 4
Views: 6579
Reputation: 1546
I have written a more compact and efficient version of K. Scott Allen's JScript inline Eval caller from here (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 could extend it to pass in variable values as well if you wanted to, e.g. pass in a dictionary of names & values. First usage of the static class will take 100-200ms, after that its pretty much instantaneous and doesn't require a separate DLL. Call JS.Prepare() to pre compile to stop the initial delay if you want.
Upvotes: 0
Reputation: 292415
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 into a DLL:
jsc /target:library /out:JsMath.dll JsMath.js
In your C# project, reference JsMath.dll and Microsoft.JScript.dll
Now you can use the Eval
method as follows:
string expression = "((34 > 0) || ('US' == 'ES')) && (4312 == 5691)";
bool result = (bool)JsMath.Eval(expression);
Benefits:
Drawbacks:
Upvotes: 7
Reputation: 498992
You can parse the expression into the .NET Expression
class and compile and run it in order to get the result.
The class already supports all the logical operations you have in your example, though it appears to be ambiguous (you are using both ==
and =
in a very similar manner).
You will have to write your own parser/converter though.
Upvotes: 3