我有一个C#控制台应用程序项目。
我有一个逻辑表达式,存储在数据库中作为nvarchar。
例如,存储的表达式是:((34 > 0) || (US == ES)) && (4312 = 5691)
当我的应用程序运行时,我想检索表达式并评估它,以便结果为true或false。
如何在运行时实现?
我有一个C#控制台应用程序项目。
我有一个逻辑表达式,存储在数据库中作为nvarchar。
例如,存储的表达式是:((34 > 0) || (US == ES)) && (4312 = 5691)
当我的应用程序运行时,我想检索表达式并评估它,以便结果为true或false。
如何在运行时实现?
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);
好处:
缺点:
JsMath.Eval("JsMath.Eval(expression)")
(可预测地抛出异常 "Out of stack space")。 - Thomas Levesqueeval
。无论如何,你需要特别小心所接受的输入... - Thomas LevesqueExpression
类,并编译并运行它以获得结果。 这个类已经支持了你在示例中使用的所有逻辑操作,尽管它看起来有一些模糊(你在非常相似的方式下同时使用了 ==
和 =
)。 但你需要自己编写解析器/转换器。我已经编写了一个更紧凑、更高效的 K. Scott Allen 的 JScript 内联 Eval 调用程序,从这里 (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);
}
}
就像这样使用:
JS.Eval<Double>("1 + 4 + 5 / 99");
返回:
5.05050505050505
如果需要的话,您可以扩展它以传递变量值,例如传递名称和值的字典。静态类的第一次使用将需要100-200毫秒,之后几乎是即时的,并且不需要单独的DLL。如果您想要停止初始延迟,请调用JS.Prepare()进行预编译。