I'm trying to parse string to create Func instance.
public class A
{
public int fieldA { get; private set; }
public bool fieldB { get; private set; }
public List<int> fieldC { get; private set; }
}
Check the condition of the instance of A class with :
{
"Type" : "A"
"Condition" : "fieldA > 0 && fieldB == true"
}
Of course the format of a string can be modified, for easier parsing.
What I want to create is actually :
Func<A, bool> condition = a => a.fieldA > 0 && a.fieldB == true;
Parsing the condition string would not be very hard, but since there are so many A instances, using reflection whenever checking the condition would not be desirable. What I want to do is "construct" this function from string in advance and cache it somewhere, and call cached function when I want to check the condition.
Could you give my any advices?
Using System.Linq.Dynamic.Core you could do something like:
public bool TestCondition(A obj, string condition)
{
var expr = DynamicExpressionParser.ParseLambda<A, bool>(ParsingConfig.Default, false, condition, new object[0]);
var func = expr.Compile();
return func(obj);
}
And invoke it like:
var testResult = TestCondition(anInstanceOfA, "fieldA > 0 && fieldB == true");
If you want to use local variables in your expression you can do:
public static bool TestCondition(A obj, string condition, IDictionary<string, object> args)
{
var expr = DynamicExpressionParser.ParseLambda(new ParameterExpression[] { Expression.Parameter(typeof(A)) },
typeof(bool),
condition,
new object[] { args });
var func = expr.Compile();
return (bool)func.DynamicInvoke(obj);
}
And invoke it like:
var locals = new Dictionary<string, object>();
locals.Add("myInt", 0);
locals.Add("myBool", true);
var check = TestCondition(obj, "fieldA > myInt && fieldB == myBool", locals);
You can also make the method generic so you can reuse it in other circumstances:
public static TOut TestCondition<TIn, TOut>(TIn obj, string condition, IDictionary<string, object> args)
{
var expr = DynamicExpressionParser.ParseLambda(new ParameterExpression[] { Expression.Parameter(typeof(TIn)) },
typeof(TOut),
condition,
new object[] { args });
var func = expr.Compile();
return (TOut)func.DynamicInvoke(obj);
}
.
.
.
TestCondition<A, bool>(obj, "fieldA > myInt && fieldB == myBool", locals)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With