【问题标题】:Parsing Conditional Expressions to String将条件表达式解析为字符串
【发布时间】:2010-11-17 01:57:26
【问题描述】:

我正在寻找一种将条件表达式解析为字符串的方法。

我能想到的最好的例子是 LINQ-to-SQL。它使用 ExpressionVisitor 来格式化“Where”子句。示例:

from a in b where a.x == 5 && a.y < 3 select a

这将转化为以下字符串(大约,MSSQL 对我来说不是最新的):

"SELECT * FROM b WHERE x = 5 AND y < 3"

根据我的阅读,这是使用 ExpressionVisitor 类完成的,如本文所述:Link

现在的问题是我不使用 LINQ,但我需要这个特殊的功能。有没有办法解析这样的条件?我愿意为反射、委托、lambda 等做任何事情。

老实说,我不认为这是可能的,但我的脑子有点炸(请阅读:如果这个问题很荒谬,那就太好了),所以我想我不妨给 S/试试看吧。

编辑:最终用法示例:

// Usage:
foo.Bar(foo => foo.X == 5 && foo.Y < 3)

// Ideal string output (variable name (foo) is not needed):
"foo.X == 5 && foo.Y < 3"

编辑 2:是的,一个数字可以小于 3 等于 5。告诉过你我的大脑被炸了。

【问题讨论】:

  • LINQ-to-SQL 正是这样做的。如果您自己编写,您将重新实现已经存在的 LINQ-to-SQL——这似乎是一种毫无意义的努力。 (但人们已经这样做了;例如 google for IQToolkit。)您说“我不使用 LINQ”,但您的代码却相反(它充满了 LINQ;表达式树被认为是 LINQ 的一部分)。

标签: c# linq expression expressionvisitor


【解决方案1】:

如果是关于构建表达式树本身,那么您可以利用 C# 编译器功能。

只要知道 Func 的类型参数,将 lambda 表达式传递给接受表达式的函数是合法的。例如

 private static void PrintExpression(Expression<Func<int, bool>> lambda)
 {
      Console.WriteLine(lambda.ToString());
 }

可以称为

 PrintExpression(a=> a > 0 && a < 5);

您可以使用泛型即兴发挥

private static void PrintExpression<T1,T2>(Expression<Func<T1, T2>> lambda)
{
      Console.WriteLine(lambda.ToString());
}

并用

调用它
   PrintExpression<int, bool>(a=> a > 0 && a < 5);

对于表达式部分的自定义打印,您可以编写一个简单的递归函数来打印表达式或任何其他适合您的逻辑。

请记住,lambda 表达式在编译时被编译成一个表达式 - 所以不能用已经编译的 Func 替换它。

作为替代方案,您始终可以构建自定义查询提供程序,但这会稍微偏离目的 - 因为您需要将其绑定为某种可查询的(再次自定义)。

【讨论】:

    【解决方案2】:

    试试这样的:

    static string GetExpressionString<T>(Expression<Func<T, bool>> expression)
    {
        return expression.Body.ToString();
    }
    

    这样使用:

    string s = GetExpressionString<Foo>(foo => foo.X == 5 && foo.Y < 3);
    

    哪个会返回:

    ((foo.X = 5) && (foo.Y < 3))
    

    【讨论】:

    • 哦,哇,我发誓当我发布我的答案时,mho 的答案不在这里!他的内容更深入一些,但我想我会留在这里。
    • 我想补充一点,删除任何强类型并允许“对象”会更有用。 :)
    猜你喜欢
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多