C#高级程序设计(九)——表达式树

表达式树的设计是基于"code as data"的思想,它把代码表示成树状的数据结构,树状结构中的每个节点都是一个表达式(这个表达式是一个广义的概念,并不是编程语言中所指的表达式语法),因此称为表达式树。

表达式树的本质在于将代码组织在数据段,而不是代码段,这对于运行时更改代码是非常重要的。

System.Linq.Expressions命名空间下含有很多类来表示不同的表达式,这些类都继承自抽象的Expression基类,Expression含有丰富的静态方法用于创建各种各样的表达式类。

一、编程方式构建表达式树

下面的代码以编程的方式构建表达式树

Expression firstArg = Expression.Constant(2);
Expression secondArg = Expression.Constant(3);
Expression add = Expression.Add(firstArg, secondArg);
Console.WriteLine(add);

上面的代码创建的表达式树如图:


二、表达式树与代理(编译表达式树成为代理)

将表达式树转化为代理的关键点在于Expression<TDelegate>类,继承关系如图: 

可以使用Expression.Lambda方法创建Expression<TDelegate>对象,Expression<TDelegate>对象包含Compile方法,用于将表达式编译成可执行代码并生成表示其lambda表达式的代理对象,

下面的代码表示转换过程: 

Expression firstArg = Expression.Constant(2);
Expression secondArg = Expression.Constant(3);
Expression add = Expression.Add(firstArg, secondArg);
Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile();
Console.WriteLine(compiled());

三、表达式树与Lambda表达式(Lambda表达式转换为表达式树)

可以通过lambda表达式构造Expression<TDelegate>对象:

Expression<Func<string, string, bool>> expression =
(x, y) => x.StartsWith(y);
var compiled = expression.Compile();
Console.WriteLine(compiled("First", "Second"));
Console.WriteLine(compiled("First", "Fir"));


下面的代码与之等价,但是用编程方式构建表达式树:

MethodInfo method = typeof(string).GetMethod
("StartsWith", new[] { typeof(string) });
var target = Expression.Parameter(typeof(string), "x");
var methodArg = Expression.Parameter(typeof(string), "y");
Expression[] methodArgs = new[] { methodArg };
Expression call = Expression.Call(target, method, methodArgs);
var lambdaParameters = new[] { target, methodArg };
var lambda = Expression.Lambda<Func<string, string, bool>>
(call, lambdaParameters);
var compiled = lambda.Compile();
Console.WriteLine(compiled("First", "Second"));
Console.WriteLine(compiled("First", "Fir"));

目前,并不是所有的lambda表达式都能转换成表达式树,只有单一表达式的lambda表达式才可以转化为表达式树,而且表达式中不能包含赋值。


四、表达式树与LINQ

表达式树主要应用在LINQ to SQL中,LINQ to SQL的目标是将LINQ请求转换为SQL语句(普通文本),但是在转换过程中我们又不想失去编译时类型检查,所以LINQ to SQL的设计思想是将LINQ查询转化成表达式树(查询中使用的lambda表达式按照某种算法转换为表达式树),然后再将表达式树转换成需要执行的SQL语句。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值