http://www.cnblogs.com/ldp615/archive/2011/09/15/expression-extension-methods.html

.net 中创建 Expression Trees 最简单的方式是使用 lambda
表达式:

1
2
Expression<Func<Person, bool>> exp =
p => p.Name.Contains("ldp") && p.Birthday.Value.Year > 1990;

其中 Person 类定义如下:

1
2
3
4
public class Person {
public string Name { get; set; }
public DateTime? Birthday { get; set; }
}

但有些时候,要动态创建 Expression Trees,我们要用到 System.Linq.Expressions 命名空间中的 Expression

使用 Expression 类 中的静态方法,前面的 Expression
Trees
 可如下创建:

1
2
3
4
5
6
7
8
9
10
var parameter = Expression.Parameter(typeof(Person), "p");
var left = Expression.Call(
Expression.Property(parameter, "Name"),
typeof(string).GetMethod("Contains"),
Expression.Constant("ldp"));
var right = Expression.GreaterThan(
Expression.Property(Expression.Property(Expression.Property(parameter, "Birthday"), "Value"), "Year"),
Expression.Constant(1990));
var body = Expression.AndAlso(left, right);
var lambda = Expression.Lambda<Func<Person, bool>>(body, parameter);

你应该注意到第 7 行高亮部分,三个重复的 Expression.Property,显得非常臃肿,导致可读性也很差。

可以用下面几个扩展方法予以简化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static class ExpressionExtensions {
public static Expression AndAlso(this Expression left, Expression right) {
return Expression.AndAlso(left, right);
}
public static Expression Call(this Expression instance, string methodName, params Expression[] arguments) {
return Expression.Call(instance, instance.Type.GetMethod(methodName), arguments);
}
public static Expression Property(this Expression expression, string propertyName) {
return Expression.Property(expression, propertyName);
}
public static Expression GreaterThan(this Expression left, Expression right) {
return Expression.GreaterThan(left, right);
}
public static Expression<TDelegate> ToLambda<TDelegate>(this Expression body, params ParameterExpression[] parameters) {
return Expression.Lambda<TDelegate>(body, parameters);
}
}

这五个扩展方法相当简单,没什么技术含量。可以根据自己需要,添加更多的扩展方法。

前面的代码简化成:

1
2
3
4
var parameter = Expression.Parameter(typeof(Person), "p");
var left = parameter.Property("Name").Call("Contains", Expression.Constant("ldp"));
var right = parameter.Property("Birthday").Property("Value").Property("Year").GreaterThan(Expression.Constant(1990));
var lambda = left.AndAlso(right).ToLambda<Func<Person, bool>>(parameter);

是不是好多了。

简单编码,快乐生活!

c# 扩展方法奇思妙用基础篇九:Expression 扩展的更多相关文章

  1. c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)

    转载地址:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html 刚看了篇文章 <Linq的Distin ...

  2. c# 扩展方法奇思妙用基础篇八:Distinct 扩展

    刚看了篇文章 <Linq的Distinct太不给力了>,文中给出了一个解决办法,略显复杂. 试想如果能写成下面的样子,是不是更简单优雅 var p1 = products.Distinct ...

  3. c# 扩展方法奇思妙用基础篇五:Dictionary<TKey, TValue> 扩展

    Dictionary<TKey, TValue>类是常用的一个基础类,但用起来有时确不是很方便.本文逐一讨论,并使用扩展方法解决. 向字典中添加键和值 添加键和值使用 Add 方法,但很多 ...

  4. c# 扩展方法 奇思妙用 高级篇 九:OrderBy(string propertyName, bool desc)

    下面是 Queryable 类 中最常用的两个排序的扩展方法: 1 2 public static IOrderedQueryable<TSource> OrderBy<TSourc ...

  5. C# 扩展方法奇思妙用高级篇六:WinForm 控件选择器

    在Web开发中,jQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象.但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器.好在我们有扩展方法,可以很方便的打造一个. ...

  6. c# 扩展方法奇思妙用

    # 扩展方法出来已久,介绍扩展方法的文章也很多,但都是笼统的.本人最近一直在思考扩展方法的应用,也悟出了一些,准备将这最近一段时间对扩展方法的思考,写成一个系列文章.每个文章只介绍一个应用方面,篇幅不 ...

  7. c# 扩展方法奇思妙用集锦

    本文转载:http://www.cnblogs.com/ldp615/archive/2009/08/07/1541404.html 其中本人觉得很经典的:c# 扩展方法奇思妙用基础篇五:Dictio ...

  8. 【mongoDB基础篇②】PHP-mongo扩展的编译以及使用

    安装PHP-mongo扩展 安装php-mongo扩展和安装其他php扩展的步骤一样: #1.首先上http://pecl.php.net上面搜索mongo,得到下载地址 wget http://pe ...

  9. Lua 学习之基础篇九<Lua 协同程序(Coroutine)>

    引言 讲到协程,首先来介绍一下线程和协程的区别 lua协程和多线程 相同之处:拥有自己独立的桟.局部变量和PC计数器,同时又与其他协程共享全局变量和其他大部分东西 不同之处:一个多线程程序可以同时运行 ...

随机推荐

  1. 程序员被老板要求两个月做个APP,要不比京东差,网友:做一个快捷方式,直接链到京东

    隔行如隔山,这句话说得一点都没错.做一个程序员,很多人都会羡慕,也有很多人会望而却步. 作为一个外行人,你别看程序员每天坐在电脑前敲敲键盘打打代码,以为很简单,其实啊也只有程序员自己明白,任何一个看似 ...

  2. zookeeper的简介和相关命令操作

    .personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...

  3. 绿色djvu阅读软件

    官方的djvu viewer都需要安装,总算找到一个绿色版的,名为STDU Viewer,可以阅读的格式包括DjVu, PDF, TIFF, XPS, FB2等,版本为1.6.2.

  4. cas5.3.1 从搭建到连接mysql(简而优美)

    前言: cas是单点登录服务框架,为单点登录业务提供了便捷服务,它分为client,server端,client端要聚合到我们自己的项目. server端要单独构建运行,本篇文章主要讲解一下cas5. ...

  5. Mysql数据库优化(1)

    1.尽量不要留null select id from t where num is null,可以,但尽量不要留null,null也占空间:使用not null填充数据库,像varchar(100)这 ...

  6. BaiduSpider:爬取百度的利器

    视频链接:https://www.zhihu.com/zvideo/1272864710321516544 BaiduSpider是一个能够爬取百度搜索结果的Python爬虫,轻量但强大.目前支持百度 ...

  7. Java - Enum 枚举类型

    目录 前言 应用 定义 基本Enum特性 Enum的静态导入 Enum中添加新方法 Switch语句中的Enum Enum的继承 EnumSet的使用 EnumMap的使用 常量相关方法 枚举值向枚举 ...

  8. NOIP 模拟 $12\; \text{简单的区间}$

    题解 签到题 求区间和为 \(k\) 的倍数的区间,我们可以转化为求左右两个端点,其前缀和相等 对于区间最大值,我们可以把其转化为一个值,它能向左,向右扩展的最远边界,一个单调栈即可 我们设一个值 \ ...

  9. AspNetCore WebApi

    需求 前几天,马老板给小明和小红一个"待办事项"网站,小明负责后端,小红负责前端,并要求网站可以同时在 Windows.和 Linux 上运行. 小明整理了一下"待办事项 ...

  10. 【spring 注解驱动开发】Spring AOP原理

    尚学堂spring 注解驱动开发学习笔记之 - AOP原理 AOP原理: 1.AOP原理-AOP功能实现 2.AOP原理-@EnableAspectJAutoProxy 3.AOP原理-Annotat ...