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. C++ //继承同名成员处理方式

    1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Base 6 { 7 pu ...

  2. 如何让win10开机默认开启小键盘?

    如何让win10开机默认开启小键盘? windows10默认是关闭小键盘的.每次输入开机密码的时候都需要按一下小键盘开启键(numlock),才能按数字键 一.运行注册表编辑器,修改InitialKe ...

  3. Linux进程理解与实践(四)wait函数处理僵尸进程

    Wait的背景 当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程 ...

  4. 关于Algorithm in Nutshell源代码

    获取源码包 "Algorithm in Nutshell"的源码包ADK-1.0.zip在这本书主页上"Download Example Code"页面的Rel ...

  5. 树莓派远程连接工具VNC使用教程

    树莓派远程连接工具VNC使用教程 背景故事 树莓派作为一款迷你小主机,大部分的使用场景都会用到远程调试,远程调试用到最多的方式一般就是VNC和SSH,VNC是远程桌面型的远程方式,简单来说就是用Win ...

  6. awk-08-综合例子

    分析nginx日志 1.统计访问IP次数 2.统计访问IP大于10次的 3.统计访问IP次数,并取出前几的访问数 4.统计时间段访问最多的IP 5.统计访问最多的10个页面 6.统计每个 URL 数量 ...

  7. Shell-03-表达式和运算符

    表达式和运算符 条件表达式语句 [ 1 -eq 1 ] [[ 1 -eq 1 ]] test 1 -eq 1 等同于 [ 1 -eq 1 ] [root@satest_192-168-3-121 sh ...

  8. jupyter notebook使用python虚拟环境

    jupyter指定环境启动 背景 系统环境中安装有jupyter及相关库,因项目需要,新建了一个torch相关的虚拟环境并安装了对应的内容, 此时,想通过系统中的jupyter启动一个可以应用虚拟环境 ...

  9. IM敏感词算法原理和实现

    效果 C++实现的代码请移步: Github-cpp-dirtyfilter 用法和效果: int main() { std::vector<std::string> words = { ...

  10. 使用VC6.0开发COM组件 - 傻瓜式,不讲理论,只讲实例

    1.创建一个ATL COM AppWizard工程,如图: