I have to filter a list of objects.
The filter should be composed by users using logical OR / AND operators, and grouping using brackets.
say, something like this:
Say, we have object MyPerson and its properties Prop1, Prop2, etc...
Having myPersons list the user could filter elements: say Prop1 == aValue AND Prop2 < otherValue OR Prop2 > thirdvalue etc...
Now, I can build the chain of expression from the atoms (thanks to Jon Skeet from this question), like this:
Func<Person, bool> isAdult = person => person.Age &g开发者_C百科t; 18;
Func<Person, bool> isInParis = person => person.Location == "Paris";
var adultInParis = And(isAdult, isInParis);
My problem now is to transform the strings from the grid "Age", ">", "18" in the function expression "person.Age > 18", in order to link with an other one from the other row.
Maybe you're looking for something like this:
class Program
{
static void Main(string[] args)
{
Func<Person, bool> isInParis = BuildFunc("Location", "==", "Paris");
Console.WriteLine(isInParis(new Person { Location = "Paris"})); // Prints true
Console.WriteLine(isInParis(new Person { Location = "Venice"})); // Prints false
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public int Weight { get; set; }
public DateTime FavouriteDay { get; set; }
public string Location { get; set; }
}
private static Func<Person, bool> BuildFunc(
string propertyName,
string comparisonOperator,
string propertyValue)
{
var parameter = Expression.Parameter(typeof (Person), "person");
var property = Expression.Property(parameter, propertyName);
var constant = Expression.Constant(propertyValue);
Expression comparison;
switch (comparisonOperator)
{
case "<":
comparison = Expression.LessThan(property, constant);
break;
case ">":
comparison = Expression.GreaterThan(property, constant);
break;
default:
comparison = Expression.Equal(property, constant);
break;
}
return Expression.Lambda<Func<Person, bool>>(comparison, parameter).Compile();
}
}
Hope it helps!
精彩评论