Reputation: 975
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
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
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
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
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