c# - 如何将字符串转换为其等效的 LINQ 表达式树?

标签 c# lambda antlr dsl predicate

这是原始问题的简化版本。

我有一个名为 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

这是我目前的想法:

  1. 在 ANTLR 中实现基本语法以支持基本的比较和逻辑运算符。我正在考虑在此处复制 Visual Basic 优先级和一些功能集:http://msdn.microsoft.com/en-us/library/fw84t893(VS.80).aspx
  2. 让 ANTLR 根据提供的字符串创建合适的 AST。
  3. 遍历 AST 并使用 Predicate Builder动态创建 Func
  4. 的框架
  5. 根据需要根据 Person 实例评估谓词

我的问题是我是不是完全烤过头了?还有其他选择吗?


编辑:选择的解决方案

我决定使用动态 Linq 库,特别是 LINQSamples 中提供的动态查询类。

代码如下:

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 包,文档 here

最佳答案

dynamic linq library帮忙吗?特别是,我认为是 Where 子句。如有必要,将其放入列表/数组中,以便在其上调用 .Where(string)!即

var people = new List<Person> { person };
int match = people.Where(filter).Any();

如果没有,编写一个解析器(在引擎盖下使用 Expression)并不是非常费力 - 我在我的火车通勤中写了一个类似的(虽然我认为我没有源代码)圣诞节前...

关于c# - 如何将字符串转换为其等效的 LINQ 表达式树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/821365/

相关文章:

c# - 如何在 Unity 中通过 X 坐标将游戏对象居中?

c# "task method"也可以是 "async"方法吗?

ruby-on-rails - rails 5.1.5 : lambda with two params for JSONB column data filtering

java - 如何在 Java 8 中映射映射中的值?

java - 如何获取规则中的所有逻辑运算符标记

c# - 如何在 Xamarin Android 中实现 JobScheduler

c# - EF 无法将 double 转换为单精度

java - 从 Java 并行流生成其他并行流并且很少失败

java - ANTLR:从 CommonTree 到有用的对象图

c# - 带有 CIL 代码编译器的 Antlr