在.NET中将复杂的布尔条件从字符串转换为布尔值

5

我需要将复杂表达式从字符串转换为布尔值。

它只能包含以下内容:
* 布尔值 (true/false),
* 括号,
* AND/OR 运算符 (&&, ||)

例如:

bool.Parse("((true || false) && (false || false)) || (true || false)"

有什么办法可以实现这个目标吗?
3个回答

6
这是一个巧妙的评估器类,可以在C#代码中提供JScript.NET Eval函数:
static public class Evaluator
{
    private const string _jscriptSource =
        @"package Evaluator
        {
           class Evaluator
           {
              public function Eval(expr : String) : String 
              { 
                 return eval(expr); 
              }
           }
        }";

    static private object _evaluator;
    static private Type _evaluatorType;

    [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline",
        Justification = "Can't be done inline - too complex")]
    static Evaluator()
    {
        InstantiateInternalEvaluator();
    }

    static private void InstantiateInternalEvaluator()
    {
        JScriptCodeProvider compiler = new JScriptCodeProvider();

        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);
    }

    static public int EvaluateToInteger(string statement)
    {
        string s = EvaluateToString(statement);
        return int.Parse(s);
    }

    static public double EvaluateToDouble(string statement)
    {
        string s = EvaluateToString(statement);
        return double.Parse(s);
    }

    static public decimal ForceEvaluateToDecimal(string statement)
    {
        decimal result;
        bool s = Decimal.TryParse(statement, out result);
        return result;
    }

    static public decimal EvaluateToDecimal(string statement)
    {
        string s = EvaluateToString(statement);
        return decimal.Parse(s);
    }

    static public string EvaluateToString(string statement)
    {
        object o = EvaluateToObject(statement);
        return o.ToString();
    }

    static public bool EvaluateToBool(string statement)
    {
        object o = EvaluateToObject(statement);
        return (bool)o;
    }

    static public object EvaluateToObject(string statement)
    {
        try
        {
            return _evaluatorType.InvokeMember(
                "Eval",
                BindingFlags.InvokeMethod,
                null,
                _evaluator,
                new object[] {statement}
                );
        }
        catch (Exception)
        {
            InstantiateInternalEvaluator();
            return null;
        }
    }
}

您只需要调用Evaluator.EvaluateToBool(string)。该代码从现有项目中获取,因此您可能需要进行微调!


太棒了! PS EvaluateToBool应该具有bool返回 - Maciej
顺便问一下,性能如何?你认为这可能是一个问题吗? - Maciej
Maciej(第一条评论)-初中生复制、粘贴和编辑错误。会编辑的,谢谢。 - David M

2

你所描述的字符串是有效的C#代码,因此如果你可以在运行时解释它,那么你就完成了。在许多语言中,这是一个内置函数。在C#中,它不是内置函数,但是你可以使用第三方库,例如这个运行时C#解释器


你提到的C#表达式运行时评估器看起来很有趣,但下载链接似乎已经失效了 - 你有源代码吗? - Maciej

0

标准方法是:

  • 对字符串进行分词
  • 构建一棵树,在每个节点上放置一个运算符,在每个叶子上放置一个操作数
  • 遍历树,计算表达式的值

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接