Just because someone stumbles loses their way,it doesn't mean they're lost forever.Sometimes we all need a little help. 人偶尔一次失足迷失了方向不等于永远会迷失下去。有时候我们只需要有人搭把手。
Program.cs
class Program
{
static void Main(string[] args)
{
BaseExpression.Test();
BaseExpressionVisitorTest.Test();
Console.Read();
}
}
BaseExpression.cs代码:
/// <summary>
/// 基本的表达式树
/// </summary>
public static void Test()
{
ParameterExpression a = Expression.Parameter(typeof(int), "a");
ParameterExpression b = Expression.Parameter(typeof(int), "b");
BinaryExpression left = Expression.Multiply(a, b);
ConstantExpression right = Expression.Constant(2, typeof(int));
BinaryExpression body = Expression.Add(left, right);
LambdaExpression lambda = Expression.Lambda<Func<int, int, int>>(body, a, b);
Console.WriteLine("lambda表达式"+lambda.ToString());
//将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示该 lambda 表达式的委托。
Func<int, int, int> ttt = lambda.Compile() as Func<int, int, int>;
Console.WriteLine("DynamicInvoke是结果:" + lambda.Compile().DynamicInvoke(3, 4));
Console.WriteLine(ttt(3, 4));
//--------------------------------------------------------------------------------------------
Expression<Func<int, int, int>> newlambda = Expression.Lambda<Func<int, int, int>>(body, a, b);
Console.WriteLine("newlambda表达式:" + newlambda.ToString());
Console.WriteLine(newlambda.Compile()(3, 4));
Func<int, int, int> mylambda = newlambda.Compile();
//--------------------------------------------------------------------------------------------
Expression<Func<int, int, int>> l2 = (x, y) => x + y + 3 + 4;
Console.WriteLine("第三个表达式树示例:"+l2.ToString());
Func<int, int> z1 = z => z + 3; //这是一个表达式,不是表达式树。
Console.WriteLine("这是一个表达式示例:" + z1.ToString());
}
BaseExpressionVisitor.cs代码,BaseExpressionVisitorTest.cs代码
public class BaseExpressionVisitor:ExpressionVisitor
{
//首先我们有一个类继承自ExpressionVisitor,里面有一个我们自己的Modify方法,然后我们直接调用Visit方法即可。上面我们提到了
//Visit方法实际上是一个入口,会根据表达式的类型调用其它的Visit方法,我们要做的就是找到对应的方法重写就可以了。但是下面有一堆
//Visit方法,我们要要覆盖哪哪些呢? 这就要看我们的表达式类型了,在我们的Where扩展方法中,我们传入的表达式树是由
//Expression.Call方法构造的,而它返回的是MethodCallExpression所以我们第一步是覆盖VisitMethodCall。
public Expression Modify(Expression exp)
{
return Visit(exp);
}
//翻译表达式树 二元运算
//ExpressionVisitor类是提供给我们的表达式树解析的帮助类,我们只要定义一个类继承ExpressionVisitor,实现一个 ResolveExpression 入口方法,
//重写VisitBinary、VisitConstant、VisitMember方法,代码如下:
protected override Expression VisitBinary(BinaryExpression node)
{
if (node.NodeType == ExpressionType.Add)
{
var left = this.Visit(node.Left);
var right = this.Visit(node.Right);
return Expression.Subtract(left, right);
}
return base.VisitBinary(node);
}
}
public class BaseExpressionVisitorTest
{
public static void Test()
{
Expression<Func<int, int, int>> expression = (a, b) => a + b * 2;
Expression newExp = new BaseExpressionVisitor().Modify(expression);
Console.WriteLine("修改前:");
Console.WriteLine(expression.ToString());
Console.WriteLine("修改后:");
Console.WriteLine(newExp.ToString());
}
}
项目运行结果: