我有一个C#控制台应用程序项目。
我有一个逻辑表达式,作为nvarchar存储在数据库中。
例如,存储的表达式是:((34> 0)||(US == ES))&& (4312 = 5691)
当我的应用程序运行时,我想检索表达式并对其进行评估,以便结果为true或false。
我怎样才能在运行时这样做?
答案 0 :(得分:7)
这是一个非常不寻常的解决方案,涉及JScript:
使用以下代码创建JScript类:
public class JsMath {
public static function Eval(expression:String) : Object {
return eval(expression);
}
}
将其编译为DLL:
jsc /target:library /out:JsMath.dll JsMath.js
在您的C#项目中,引用JsMath.dll和Microsoft.JScript.dll
现在您可以使用Eval
方法,如下所示:
string expression = "((34 > 0) || ('US' == 'ES')) && (4312 == 5691)";
bool result = (bool)JsMath.Eval(expression);
优点:
缺点:
答案 1 :(得分:3)
您可以将表达式解析为.NET Expression
类,然后编译并运行它以获得结果。
该类已经支持您示例中的所有逻辑操作,但它似乎含糊不清(您以非常类似的方式使用==
和=
)。
您必须编写自己的解析器/转换器。
答案 2 :(得分:0)
我从此处(https://odetocode.com/articles/80.aspx)编写了K. Scott Allen的JScript内联Eval调用程序的更紧凑和有效的版本:
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);
}
}
只需像这样使用它:
JS.Eval<Double>("1 + 4 + 5 / 99");
返回:
5.05050505050505
如果需要,您也可以扩展它以传递变量值。传入名称和值的字典。静态类的首次使用将花费100-200ms,之后它几乎是瞬时的,不需要单独的DLL。如果需要,可以调用JS.Prepare()进行预编译以停止初始延迟。