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. Bugku-misc 1-8题总结

    1.签到题 略过 2.这是一张单纯的图片 拉入winhex,在最后面有一段Uniocde编码,解码得到flag. 3.隐写 题目是隐写,binwalk打开分析 得到两个Zlib(提供数据压缩用的函式库 ...

  2. 2021 年 iOS 应用程序开发七种最佳语言

    移动应用程序现在几乎是每个在线业务的必备品.最新的 StatCounter 数据显示,多达56% 的在线连接是通过移动设备建立的,这使它们高于平板电脑和计算机.更重要的是,同一个消息来源说,其中27% ...

  3. Ubuntu 查询用户账号

    查看当前登录 who users 查看系统中所有用户: grep bash /etc/passwd XXXX-VirtualBox:~/桌面$ w 13:23:26 up 15 min, 1 user ...

  4. 蓝桥杯练习-各大OJ平台介绍

    校赛准备的不够充分,简单题失分太遗憾, 有幸参加到省赛,这次先码一下练习平台,等学期结束忙完之后好好练习! 1.题库与网站资源题库-在线提交系统(Online Judge)简介   下面是几个比较大的 ...

  5. STM32—位带操作

    STM32中的位带操作: 名字为位带操作,实际上是对位的操作,位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见. 51 单片机中通过关键字 sbit 来实现位定义, STM32 ...

  6. 题解 P3941 入阵曲

    题解 观察数据范围,可以 \(\mathcal O(n^2m^2)\) 暴力计算,而加上特殊性质,则可以骗到 \(75pts\) 正解: 我们发现,在一维情况下,\(\mod k\) 相同的前缀和相减 ...

  7. 痞子衡嵌入式:其实i.MXRT下改造FlexSPI driver同样支持AHB方式去写入NOR Flash

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT下改造FlexSPI driver以AHB方式去写入NOR Flash. 痞子衡前段时间写过一篇 <串行NAND Fl ...

  8. Ubuntu18.04忘记root密码,重置root密码

    输入命令,更新root密码: sudo passwd root 然后输入新密码,再输入一次确认新密码,新密码更新完毕! 切换root账号: su 如下图所示,发现已经由zyw账号切换到root账号了!

  9. Vue 如何实现一个底部导航栏组件

    参考网址: https://www.jianshu.com/p/088936b7b1bd/ Vue 如何实现一个底部导航栏组件 可以看到父组件是知道我点击了底部TabBar的哪个item的. 实现 实 ...

  10. Qt元对象和属性系统详解

    Qt 是一个用标准 C++ 编写的跨平台开发类库,它对标准 C++ 进行了扩展,引入了元对象系统.信号与槽.属性等特性,使应用程序的开发变得更高效. 本节将介绍 Qt 的这些核心特点,对于理解和编写高 ...