表达式树:分别将 + 1 / -1分别替换为增量/有害操作

问题描述 投票:1回答:1

我想用表达式树将() => a - 1 + b + 1 lambda转换为类似() => a-- + b++的东西。

我实现了从ExpressionTreeTransformer.cs继承并覆盖ExpressionVisitor.cs方法的类VisitBinary

protected override Expression VisitBinary(BinaryExpression node)
        {
            if (!TryGetNumberValueFromExpressionNode(node.Left, out var leftNodeValue))
            {
                return base.VisitBinary(node);
            }

            if (!TryGetNumberValueFromExpressionNode(node.Right, out var rightNodeValue) || rightNodeValue != 1)
            {
                return base.VisitBinary(node);
            }

            var resultedExpression = node.NodeType switch
            {
                ExpressionType.Add => Expression.Increment(Expression.Constant(leftNodeValue)),
                ExpressionType.Subtract => Expression.Decrement(Expression.Constant(leftNodeValue)),
                _ => base.VisitBinary(node)
            };

            return resultedExpression;
        }

[如果加上像() => (a - 1) + (b + 1)这样的括号,效果很好,但是如果我们尝试()=> a - 1 + b + 1]则不会。>

经过一番调查,我发现那个原因就是表达式树如何构建节点。没有括号的步骤如下所示:

  1. 左(a-1)+右(b)
  2. 左(1步的结果)+右(1)
  3. 表达式节点在处理程序链中处理:

_expressionHandlers = new MemberExpressionHandler();
_expressionHandlers.SetSuccessor(new ConstantExpressionHandler());

变量处理程序:

public class MemberExpressionHandler : AbstractTreeExpressionHandler
    {
        public override bool Handle(Expression expressionNode, out int nodeValue)
        {
            if (expressionNode is MemberExpression memberExpression)
            {
                var constantExpression = memberExpression.Expression as ConstantExpression;
                var field = (FieldInfo)memberExpression.Member;

                if (constantExpression != null)
                {
                    var value = field.GetValue(constantExpression.Value);
                    var isNumber = int.TryParse(value.ToString(), out nodeValue);

                    if (isNumber)
                    {
                        return true;
                    }
                }
            }
            else
            {
                if (_successor != null)
                {
                    return _successor.Handle(expressionNode, out nodeValue);
                }
            }

            nodeValue = 0;

            return false;
        }
    }

常量处理程序:

public class ConstantExpressionHandler : AbstractTreeExpressionHandler
    {
        public override bool Handle(Expression expressionNode, out int nodeValue)
        {
            var isConstant = expressionNode is ConstantExpression;
            var isNumber = int.TryParse(((ConstantExpression)expressionNode).Value.ToString(), out nodeValue);

            if (isConstant && isNumber)
            {
                return true;
            }

            return false;
        }
    }

问:我很困,请分享您的经验,如何以正确的方式解决此任务

P.s结果:

  • 带括号:()=> (Decrement(0) + Increment(1))
  • 没有:() => ((Decrement(0) + value(ExpressionTreeModule.Program+<>c__DisplayClass0_0).b) + 1)

我想用表达式树将(-= + a-1 + b + 1 lambda)转换为(()=> a-- + b ++)。我实现了从ExpressionVisitor.cs继承的类ExpressionTreeTransformer.cs ...

c# linq expression expression-trees
1个回答
0
投票

[我认为,当找到1的恒定加减时,您需要检查左侧,并确定是否可以将加减乘以增量/减量。这是我的示例代码:

© www.soinside.com 2019 - 2024. All rights reserved.