Kacper Stachowski
Kacper Stachowski

Reputation: 975

C# Convert string to if condition

Is it possible to convert string

"value > 5 && value <= 10" 

to if statement?

if (value > 5 && value <= 10)
{
   //do something
}

I have conditions stored as strings in DB, so it must be a dynamic conversion

Upvotes: 5

Views: 4899

Answers (4)

CSDev
CSDev

Reputation: 3235

Use Compute method of System.Data.DataTable:

static class ExpressionHelper
{
    private static readonly DataTable dt = new DataTable();
    private static readonly Dictionary<string, string> expressionCache = new Dictionary<string, string>();
    private static readonly Dictionary<string, object> resultCache = new Dictionary<string, object>();

    // to be amended with necessary transforms
    private static readonly (string old, string @new)[] tokens = new[] { ("&&", "AND"), ("||", "OR") };

    public static T Compute<T>(this string expression, params (string name, object value)[] arguments) =>
        (T)Convert.ChangeType(expression.Transform().GetResult(arguments), typeof(T));

    private static object GetResult(this string expression, params (string name, object value)[] arguments)
    {
        foreach (var arg in arguments)
            expression = expression.Replace(arg.name, arg.value.ToString());

        if (resultCache.TryGetValue(expression, out var result))
            return result;

        return resultCache[expression] = dt.Compute(expression, string.Empty);
    }

    private static string Transform(this string expression)
    {
        if (expressionCache.TryGetValue(expression, out var result))
            return result;

        result = expression;
        foreach (var t in tokens)
            result = result.Replace(t.old, t.@new);

        return expressionCache[expression] = result;
    }
}

Usage

var expr = "value > 5 && value <= 10";
var a1 = expr.Compute<bool>(("value", 5)); // false
var a2 = expr.Compute<bool>(("value", 7)); // true
var a3 = expr.Compute<bool>(("value", 11)); // false

Upvotes: 2

Assassin
Assassin

Reputation: 1302

I am afraid that you will have to create the simple parser for that.

You can try use something like FParsec. This is an F# parser library. I am not aware of such code in C#

Upvotes: 0

HarryPotter
HarryPotter

Reputation: 119

Instead you can treat it as a javascript line and can get this done using Windows Script Engines, provided value is a real value instead of variable name.

 if(ScriptEngine.Eval("jscript", "value > 5 && value <= 10"))
   {
     //Your logic
   }

Or if its a variable then you can build a JS function like below to accomplish this:

using (ScriptEngine engine = new ScriptEngine("jscript"))
{
  string JSfunction =  "MyFunc(value){return " + "value > 5 && value <= 10" + "}";

  ParsedScript parsed = engine.Parse(JSfunction);
  if(parsed.CallMethod("MyFunc", 3))
  {  
   // Your Logic
  }
}

Upvotes: 4

Johnny
Johnny

Reputation: 9519

You could use Linq.Expression to build up the expression tree, the one you provided:

"value > 5 && value <= 10"

var val = Expression.Parameter(typeof(int), "x");
var body = Expression.And(
     Expression.MakeBinary(ExpressionType.GreaterThan, val, Expression.Constant(5)), 
     Expression.MakeBinary(ExpressionType.LessThanOrEqual, val, Expression.Constant(10)));

var lambda = Expression.Lambda<Func<int, bool>>(exp, val);
bool b = lambda.Compile().Invoke(6); //true
bool b = lambda.Compile().Invoke(11); //false

This is just an example to get some idea, still you need a smart way to parse and build the tree.

Upvotes: 1

Related Questions