如何动态创建带有括号的“System.Linq.Expression”表达式

3

我需要动态地创建表达式。我的问题是如何在System.Linq.Expression中添加括号以处理优先级...

int a = 1, b = 1, c = 1, d = 2;

我已将以下表达式转换为:

 var v = a > 1 || b > 1 && c > 1 || d > 1;
 Expression case1Expr =

                Expression.AndAlso(
                Expression.OrElse(
                Expression.GreaterThan(Expression.Parameter(typeof(int), "a"), Expression.Constant(1)),
                Expression.GreaterThan(Expression.Parameter(typeof(int), "b"), Expression.Constant(1))),


                Expression.OrElse(
                Expression.GreaterThan(Expression.Parameter(typeof(int), "c"), Expression.Constant(1)),
                Expression.GreaterThan(Expression.Parameter(typeof(int), "d"), Expression.Constant(1))));

但是如何转换带括号的表达式?
var v2 = (a > 1 || b > 1) && (c > 1 || d > 1);
4个回答

2
只是为了进一步扩展其他答案; 括号是我们需要保留中缀表示法,即用于描述方程式(A OP B)的模糊性。其他表示法,例如后缀(A B OP),不需要它。
在您的情况下,您正在组合一个表达式树,这也是明确无误的,即只有一种解释方法。因此,在表达式树中没有括号的概念。树的“形状”确定了操作的顺序。

1
您可以通过构建表达式树来指定优先级。 && 运算符通常比 || 运算符具有更高的优先级,因此您的转换将应用于带括号的表达式。否则,它将只是:
var v = a > 1 || b > 1 && c > 1 || d > 1;

OrElse(
    GreaterThan(a > 1),

    OrElse(
      AndAlso(
        GreaterThan(b > 1),
        GreaterThan(c > 1)),
      GreaterThan(d > 1)))

0

您已经拥有该语义的代码。当您在您拥有的确切代码上调用ToString时,会得到如下结果:

(((a > 1) OrElse (b > 1)) AndAlso ((c > 1) OrElse (d > 1)))

不需要特定的表达式来表示括号;括号是在你组合表达式的方式中隐含的。在你的代码中,你将Or表达式传递给And表达式,因此Or表达式将被加上括号。


-1

我可能没有理解你的问题,但你只需要这样做:

Expression first = Expression.OrElse(
    Expression.GreaterThan(Expression.Parameter(typeof(int), "a"), Expression.Constant(1)),
    Expression.GreaterThan(Expression.Parameter(typeof(int), "b"), Expression.Constant(1)));

Expression second = Expression.OrElse(
    Expression.GreaterThan(Expression.Parameter(typeof(int), "c"), Expression.Constant(1)),
    Expression.GreaterThan(Expression.Parameter(typeof(int), "d"), Expression.Constant(1)));

Expression final = Expression.AndAlso(first, second);

结果为:(((a > 1) OrElse (b > 1)) AndAlso ((c > 1) OrElse (d > 1)))


这正是OP已经在做的事情;没有必要将值放入命名变量中。 - Servy
在提出问题后,我也意识到了尝试它的重要性。 - Milan Raval
@Servy同意。我只是为了清晰而将其分解。米兰,你可能想删除这个问题,因为你已经有了解决方案! :) - AlG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接