龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C#开发 >

详解C# Lambda表达式的动态生成(1)

时间:2011-04-12 23:18来源:未知 作者:admin 点击:
分享到:
对于C# Lambda的理解我们在之前的文章中已经讲述过了,那么作为Delegate的进化使用,为了让代码简洁和优雅的呈现,C# Lambda表达式的使用功不可灭,那么依托外部条件如何动态构建C# L

对于C# Lambda的理解我们在之前的文章中已经讲述过了,那么作为Delegate的进化使用,为了让代码简洁和优雅的呈现,C# Lambda表达式的使用功不可灭,那么依托外部条件如何动态构建C# Lambda表达式呢。下面让我们来具体的看看实施。

或许你会奇怪这个需求是如何产生的…… 首先,Lambda 在 DLinq 中承担了以往 T-SQL 的部分角色;其次,在数据库设计中,我们往往需要依据外部未知的动态条件组合来查询数据。而问题在于作为一种静态语言,我们显然无法用动态语法或者拼接字符串的方法来创建一个Delegate/Lambda,那么如何达到类似的目的呢?CodeDom?Emit?或许最佳的选择是 System.Linq.Expressions.Expression。

1、首先我们了解一个简单C# Lambda表达式的构成。

  1. i => i > 5 

在这个表达式中,"i" 被称为 Parameter,"i > 5" 是 Body。我们可以对 Body 进行更进一步的分解,那么 "i > 5" 分别包含参数(i)、操作符(>)以及一个常数(5)。所有这些通过特定顺序的组合,从而构建一个完整的 Lambda 表达式。

2、我们通过一些例子,来学习如何动态构建C# Lambda表达式

动态构建C# Lambda表达式例子1

  1. var ints =   
  2. new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  
  3. //var r = ints.Where(i => i > 5);   
  4. // 要实现的表达式  
  5.  
  6. // 创建参数 i  
  7. var parameter =   
  8. Expression.Parameter(typeof(int), "i");  
  9.  
  10. // 创建常量5  
  11. var constant =   
  12. Expression.Constant(5);  
  13.  
  14. // 创建比较表达式 i > 5  
  15. var bin =   
  16. Expression.GreaterThan(parameter, constant);  
  17.  
  18. // 获取Lambda表达式  
  19. var lambda =   
  20. Expression.Lambda<Func<intbool>>(bin, parameter);  
  21.  
  22. // 通过 Compile 方法获取 Delegate  
  23. var _r = ints.Where(lambda.Compile());  

在代码中设置断点,我们可以看到调试器中显示的表达式信息。

图1

.NET FX 3.5 中为 Lambda 新增了一些委托类型。

(1) 用于处理无返回数据的 Action。

  1. public delegate void   
  2. Action()  
  3. public delegate void   
  4. Action<T> (T arg)  
  5. public delegate void   
  6. Action<T1, T2> (T1 arg1, T2 arg2)  
  7. public delegate void   
  8. Action<T1, T2, T3>   
  9. (T1 arg1, T2 arg2, T3 arg3)  
  10. public delegate void   
  11. Action<T1, T2, T3, T4>   
  12. (T1 arg1, T2 arg2, T3 arg3, T4 arg4) 

(2) 用于处理带返回数据的 Func。

  1. public delegate TResult   
  2. Func<TResult> ()  
  3. public delegate TResult  
  4. Func<T, TResult> (T arg)  
  5. public delegate TResult   
  6. Func<T1, T2, TResult>   
  7. (T1 arg1, T2 arg2)  
  8. public delegate TResult   
  9. Func<T1, T2, T3, TResult>   
  10. (T1 arg1, T2 arg2, T3 arg3)  
  11. public delegate TResult   
  12. Func<T1, T2, T3, T4, TResult>   
  13. (T1 arg1, T2 arg2, T3 arg3, T4 arg4) 

我们还可以进行更复杂的组合。

动态构建C# Lambda表达式例子2

  1. var ints =   
  2. new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  
  3. // var r =   
  4. ints.Where(i => i > 5 && i <= 7);  
  5.  // 要实现的表达式  
  6.  
  7. // 创建参数 i  
  8. var parameter =   
  9. Expression.Parameter(typeof(int), "i");  
  10.  
  11. // 创建表达式 i > 5   
  12. var con1 =   
  13. Expression.Constant(5);  
  14. var bin1 =   
  15. Expression.GreaterThan(parameter, con1);  
  16.  
  17. // 创建表达式 i <= 7  
  18. var con2 =   
  19. Expression.Constant(7);  
  20. var bin2 =   
  21. Expression.LessThanOrEqual(parameter, con2);  
  22.  
  23. // 组合两个表达式  
  24. var body =   
  25. Expression.And(bin1, bin2);  
  26.  
  27. // 获取 Lambda 表达式  
  28. var lambda =   
  29. Expression.Lambda<Func<intbool>>(body, parameter);  
  30.  
  31. var _r = ints.Where(lambda.Compile());  

在例子2中,我们对复杂的表达式进行了分解,并使用 And 完成多个表达式的组装,由此我们可以创建更加复杂的逻辑组合,比如例子3。

共2页: 1 [2] 下一页
【内容导航】
 第 1 页:动态构建C# Lambda表达式简介

精彩图集

赞助商链接