我想用表达式树将() => 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
]则不会。>
经过一番调查,我发现那个原因就是表达式树如何构建节点。没有括号的步骤如下所示:
表达式节点在处理程序链中处理:
_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 ...
[我认为,当找到1
的恒定加减时,您需要检查左侧,并确定是否可以将加减乘以增量/减量。这是我的示例代码: