-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExpVisitor.cs
69 lines (56 loc) · 2.64 KB
/
ExpVisitor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace ExpressionTree1
{
public class ExpVisitor : ExpressionVisitor
{
private readonly Dictionary<string, object> values =
new Dictionary<string, object> {{"a", 12}, {"b", 7}};
protected override Expression VisitBinary(BinaryExpression node)
{
if (node.Equals(null))
return base.VisitBinary(node);
var isAddOrSub = !node.NodeType.Equals(ExpressionType.Add) &&
!node.NodeType.Equals(ExpressionType.Subtract);
ConstantExpression constant = null;
if (isAddOrSub)
{
if (node.Left.NodeType.Equals(ExpressionType.Constant) ||
node.Right.NodeType.Equals(ExpressionType.Constant))
constant = node.Left.NodeType.Equals(ExpressionType.Constant)
? (ConstantExpression) node.Left
: (ConstantExpression) node.Right;
ParameterExpression parameter = null;
if (node.Left.NodeType.Equals(ExpressionType.Parameter) ||
node.Right.NodeType.Equals(ExpressionType.Parameter))
parameter = node.Left.NodeType.Equals(ExpressionType.Parameter)
? (ParameterExpression) node.Left
: (ParameterExpression) node.Right;
if (!NeedToTransform(parameter, constant))
return base.VisitBinary(node);
return node.NodeType == ExpressionType.Add ? Expression.Increment(node) : Expression.Decrement(node);
}
return base.VisitBinary(node);
}
private static bool NeedToTransform(ParameterExpression parameter, ConstantExpression constant)
{
if (parameter != null && constant != null) return parameter.Name.Equals("1") || constant.Value.Equals(1);
return parameter?.Name.Equals("1") ?? (constant?.Value.Equals(1) ?? false);
}
protected override Expression VisitLambda<T>(Expression<T> node)
{
return node.Parameters.Any(p => values.ContainsKey(p.Name))
? Visit(Expression.Lambda(node.Body, node.Parameters.Where(p => !values.ContainsKey(p.Name))))
: base.VisitLambda(node);
}
protected override Expression VisitParameter(ParameterExpression node)
{
var exp = values.ContainsKey(node.Name)
? Expression.Constant(values[node.Name])
: base.VisitParameter(node);
return exp;
}
}
}