Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert complex bool condition from string to bool in .NET

I need to parse complex expresion from string to bool.

It can only contain:
* boolean values (true/false),
* parenthesis,
* AND/OR operands (&&, ||)

Eg:

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

Any idea how to achieve this?

like image 911
Maciej Avatar asked Mar 27 '09 14:03

Maciej


People also ask

Under which conditions does Boolean convert a string to true?

The boolean returned represents the value true if the string argument is not null and is equal, ignoring case, to the string "true".

What does bool TryParse do?

TryParse(String, Boolean) Tries to convert the specified string representation of a logical value to its Boolean equivalent.


2 Answers

Here's a cunning evaluator class that gives you the JScript.NET Eval function within C# code:

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

You just then call Evaluator.EvaluateToBool(string). Lifted from an existing project, so you may want to tweak!

like image 133
David M Avatar answered Sep 21 '22 05:09

David M


The string you described is valid C# code, so if you can interpret it at runtime you're done. In many languages this is a built in function. In C# it is not, but you can use a 3rd party library such as this runtime C# interpreter

like image 43
RossFabricant Avatar answered Sep 24 '22 05:09

RossFabricant