这是原始问题的简化版本。
我有一个叫Person的课:
public class Person {
public string Name { get; set; }
public int Age { get; set; }
public int Weight { get; set; }
public DateTime FavouriteDay { get; set; }
}
...然后说一个实例:
var bob = new Person {
Name = "Bob",
Age = 30,
Weight = 213,
FavouriteDay = '1/1/2000'
}
我想在我最喜欢的文本编辑器中将以下内容写为字符串。
(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3
我想使用此字符串和我的对象实例并评估TRUE或FALSE-即在对象实例上评估Func <Person,bool>。
这是我目前的想法:
- 在ANTLR中实现基本语法,以支持基本比较和逻辑运算符。我正在考虑在此处复制Visual Basic优先级和某些功能集:http : //msdn.microsoft.com/zh-cn/library/fw84t893(VS.80).aspx
- 让ANTLR从提供的字符串中创建合适的AST。
- 遍历AST并使用Predicate Builder框架动态创建Func <Person,bool>
- 根据需要评估Person的谓词
我的问题是我是否完全对此负担过重?有其他选择吗?
编辑:选择解决方案
我决定使用Dynamic Linq库,尤其是LINQSamples中提供的Dynamic Query类。
代码如下:
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();
}
}
}
结果的类型为System.Boolean,在这种情况下为TRUE。
非常感谢Marc Gravell。
在此处包含System.Linq.Dynamic nuget软件包,文档