This is a simplified version of the original problem.
I have a class called Person:
public class Person {
public string Name { get; set; }
public int Age { get; set; }
public int Weight { get; set; }
public DateTime FavouriteDay { get; set; }
}
...and lets say an instance:
var bob = new Person {
Name = "Bob",
Age = 30,
Weight = 213,
FavouriteDay = '1/1/2000'
}
I would like to write the following as a string in my favourite text editor....
(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3
I would like to take this string and my object instance and evaluate a TRUE or FALSE - i.e. evaluating a Func<Person, bool> on the object instance.
Here are my current thoughts:
My question is have I totally overbaked this? any alternatives?
I decided to use the Dynamic Linq Library, specifically the Dynamic Query class provided in the LINQSamples.
Code below:
using System;
using System.Linq.Expressions;
using System.Linq.Dynamic;
namespace ExpressionParser
{
class Program
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public int Weight { get; set; }
public DateTime FavouriteDay { get; set; }
}
static void Main()
{
const string exp = @"(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3";
var p = Expression.Parameter(typeof(Person), "Person");
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, exp);
var bob = new Person
{
Name = "Bob",
Age = 30,
Weight = 213,
FavouriteDay = new DateTime(2000,1,1)
};
var result = e.Compile().DynamicInvoke(bob);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
Result is of type System.Boolean, and in this instance is TRUE.
Many thanks to Marc Gravell.
Include System.Linq.Dynamic nuget package, documentation here
Would the dynamic linq library help here? In particular, I'm thinking as a Where
clause. If necessary, put it inside a list/array just to call .Where(string)
on it! i.e.
var people = new List<Person> { person };
int match = people.Where(filter).Any();
If not, writing a parser (using Expression
under the hood) isn't hugely taxing - I wrote one similar (although I don't think I have the source) in my train commute just before xmas...