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

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

我们提供的服务有:成都做网站、网站建设、微信公众号开发、网站优化、网站认证、赵县ssl等。为上1000+企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的赵县网站制作公司

或许你会奇怪这个需求是如何产生的…… 首先,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>(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 arg)  
  5. public delegate void   
  6. Action (T1 arg1, T2 arg2)  
  7. public delegate void   
  8. Action   
  9. (T1 arg1, T2 arg2, T3 arg3)  
  10. public delegate void   
  11. Action   
  12. (T1 arg1, T2 arg2, T3 arg3, T4 arg4) 

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

 
 
 
  1. public delegate TResult   
  2. Func ()  
  3. public delegate TResult  
  4. Func (T arg)  
  5. public delegate TResult   
  6. Func   
  7. (T1 arg1, T2 arg2)  
  8. public delegate TResult   
  9. Func   
  10. (T1 arg1, T2 arg2, T3 arg3)  
  11. public delegate TResult   
  12. Func   
  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>(body, parameter);  
  30.  
  31. var _r = ints.Where(lambda.Compile());  

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

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

 
 
 
  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) || (i == 3));   
  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. // 创建表达式 i == 3  
  24. var con3 =   
  25. Expression.Constant(3);  
  26. var bin3 =   
  27. Expression.Equal(parameter, con3);  
  28.  
  29. // 组合 i > 5 && i <= 7  
  30. var body =   
  31. Expression.And(bin1, bin2);  
  32.  
  33. // 组合 ( i > 5 && i <= 7) OR (i == 3)  
  34. body = Expression.Or(body, bin3);  
  35.  
  36. var lambda =   
  37. Expression.Lambda>  
  38. (body, parameter);  
  39. var _r = ints.Where(lambda.Compile());  

我们继续看几个常见的例子。

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

 
 
 
  1. var ints =   
  2. new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  
  3. //var r = ints.Select(i => i % 2 == 0 ? i : 0);   
  4. // 要实现的表达式  
  5.  
  6. // 创建参数 i  
  7. var parameter =   
  8. Expression.Parameter(typeof(int), "i");  
  9.  
  10. // 创建表达式 i % 2  
  11. var con1 =   
  12. Expression.Constant(2);  
  13. var bin1 =   
  14. Expression.Modulo(parameter, con1);  
  15.  
  16. // 创建表达式 (i % 2) == 0  
  17. var con2 =   
  18. Expression.Constant(0);  
  19. var bin2 =   
  20. Expression.Equal(bin1, con2);  
  21.  
  22. // 创建表达式 IIF(((i % 2) = 0), i, 0)  
  23. var bin3 =   
  24. Expression.Condition  
  25. (bin2, parameter, Expression.Constant(0));  
  26.  
  27. var lambda =   
  28. Expression.Lambda>(bin3, parameter);  
  29. var _r = ints.Select(lambda.Compile());  

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

 
 
 
  1. var ints =   
  2. new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  
  3. // Array.ForEach(ints, i => Console.WriteLine(i));  
  4.  // 要实现的表达式  
  5.  
  6. // 创建参数i  
  7. var parameter =   
  8. Expression.Parameter(typeof(int), "i");  
  9.  
  10. // 获取 Console.WriteLine MethodInfo  
  11. MethodInfo method =   
  12. typeof(Console).GetMethod(  
  13. "WriteLine", new Type[] { typeof(int) });  
  14.  
  15. // 创建表达式   
  16. var call = Expression.Call(method, parameter);  
  17.  
  18. var lambda =   
  19. Expression.Lambda>(call, parameter);  
  20. Array.ForEach(  
  21. ints, lambda.Compile());  

是该花点时间去好好研究一下 System.Linq.Expressions Namespace 了……

动态构建C# Lambda表达式的基本内容就向你介绍到这里,希望那个对你了解和掌握使用动态构建C# Lambda表达式有所帮助。

【编辑推荐】

  1. LINQ to SQL删除实现体会小结
  2. LINQ删除记录的操作实现
  3. 实现LINQ删除数据的巧妙方法
  4. 详解实现LINQ to SQL删除行
  5. C# Lambda Expression概念浅析

分享题目:详解C#Lambda表达式的动态生成
当前链接:http://www.shufengxianlan.com/qtweb/news25/498875.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联