using System.Collections.Generic;
using System.Linq.Expressions;
public int Age { get; set; }
public string Name { get; set; }
public List<string> LstTags { get; set; }
public string MemberName { get; set; }
public string Operator { get; set; }
public string TargetValue { get; set; }
public Rule(string MemberName, string Operator, string TargetValue)
this.MemberName = MemberName;
this.Operator = Operator;
this.TargetValue = TargetValue;
public static Func<T, bool> CompileRule<T>(Rule r)
var paramUser = Expression.Parameter(typeof (User));
Expression expr = BuildExpr<T>(r, paramUser);
return Expression.Lambda<Func<T, bool>>(expr, paramUser).Compile();
static Expression BuildExpr<T>(Rule rule, Expression param)
var left = Expression.Property(param, rule.MemberName);
var leftType = typeof (T).GetProperty(rule.MemberName).PropertyType;
if (Enum.TryParse(rule.Operator, out tBinary))
var right = Expression.Constant(Convert.ChangeType(rule.TargetValue, leftType));
return Expression.MakeBinary(tBinary, left, right);
var method = leftType.GetMethod(rule.Operator);
var tParam = method.GetParameters()[0].ParameterType;
var right = Expression.Constant(Convert.ChangeType(rule.TargetValue, tParam));
return Expression.Call(left, method, right);
public static void Main()
List<Rule> lstRules = new List<Rule> {new Rule("Age", "GreaterThan", "20"), new Rule("Name", "Equal", "john"), new Rule("LstTags", "Contains", "a1")};
var user1 = new User {Age = 13, Name = "royi", LstTags = new List<string> {"a", "b", "c"}};
var user2 = new User {Age = 33, Name = "john", LstTags = new List<string> {"a1", "b1", "c1"}};
var user3 = new User {Age = 53, Name = "paul", LstTags = new List<string> {"a2", "b2", "c2"}};
var compiledRules = lstRules.Select(r => CompileRule<User>(r)).ToList();
var lst = new List<User> {user1, user2, user3};
foreach (var user in lst)
Console.WriteLine(compiledRules.All(rule => rule(user)));