将条件表达式解析为字符串

发布于 2024-10-02 11:11:04 字数 914 浏览 5 评论 0原文

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

我能想到的最好的例子是 LINQ-to-SQL。它使用 ExpressionVisitors 来格式化“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 类完成的,如本文中所述: 链接

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

老实说,我认为这是不可能的,但我的大脑有点烧焦(阅读:如果问题很荒谬,请表现得友善一点) ),所以我想我不妨尝试一下 S/O。

编辑:最终用法示例:

// 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。告诉你我的大脑被炸了。

I'm looking for a way of parsing a conditional expression to a string.

The best example I can think of is LINQ-to-SQL. It uses ExpressionVisitors to format "Where" clauses. Example:

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

That would translate into the following string (approximately, MSSQL is not current for me):

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

From what I've read, this was done using the ExpressionVisitor class, as explained in this article: Link

Now the problem is that I don't use LINQ, but I need this particular functionality. Is there a way of parsing a condition like that? I'm willing to do anything with reflection, delegates, lambda, etc.

Honestly, I don't think it's possible, but my brain is a bit fried (read: be nice if the question is ridiculous), so I figured I might just as well give S/O a try.

EDIT: Final usage example:

// 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"

EDIT 2: Yes, a number can be lower than 3 and equal to 5. Told you my brain is fried.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

此岸叶落 2024-10-09 11:11:04

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

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

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

可以调用 as

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

您可以即兴使用泛型 as

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 替换它。

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

If it is about about building the expression tree itself, then you could leverage C# compiler abilities.

It is legal to pass a lambda expression to a function acception an Expression>, as long as type arguments of Func are known. For example

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

can be called as

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

You can improvise with generics as

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

and calling it with

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

For custom printing of the expression part, you can write a simple recursive function that prints an expression or any other logic that suits you.

Remember, the lambda expression is compiled into an Expression at compile time - so can't subsititute it with already compiled Func.

As an alternative to this, you can always build a custom query provider, but that would be slightly deviating from the purpose - as you'd need to bind it some sort of queryable (custom again).

将军与妓 2024-10-09 11:11:04

尝试这样的事情:

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))

Try something like this:

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

Usage as so:

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

Which will return:

((foo.X = 5) && (foo.Y < 3))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文