C# lamda表达式学习


C# Lambda表达式的概念大家一定已经清楚了,那么如何动态生成C# Lambda表达式呢?具体的操作是什么呢?有什么需要注意的呢?那么本文就向你介绍具体的内容。

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

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

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


i => i > 5

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

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

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


var ints =    
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };   
//var r = ints.Where(i => i > 5);    
// 要实现的表达式   
 
// 创建参数 i   
var parameter =    
Expression.Parameter(typeof(int), "i");   
 
// 创建常量5   
var constant =    
Expression.Constant(5);   
 
// 创建比较表达式 i > 5   
var bin =    
Expression.GreaterThan(parameter, constant);   
 
// 获取Lambda表达式   
var lambda =    
Expression.Lambda>(bin, parameter);   
 
// 通过 Compile 方法获取 Delegate   
var _r = ints.Where(lambda.Compile());  

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

图1

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

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


public delegate void    
Action()   
public delegate void    
Action (T arg)   
public delegate void    
Action (T1 arg1, T2 arg2)   
public delegate void    
Action    
(T1 arg1, T2 arg2, T3 arg3)   
public delegate void    
Action    
(T1 arg1, T2 arg2, T3 arg3, T4 arg4)

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


public delegate TResult    
Func ()   
public delegate TResult   
Func (T arg)   
public delegate TResult    
Func    
(T1 arg1, T2 arg2)   
public delegate TResult    
Func    
(T1 arg1, T2 arg2, T3 arg3)   
public delegate TResult    
Func    
(T1 arg1, T2 arg2, T3 arg3, T4 arg4)

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

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


var ints =    
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };   
// var r =    
ints.Where(i => i > 5 && i <= 7);   
 // 要实现的表达式   
 
// 创建参数 i   
var parameter =    
Expression.Parameter(typeof(int), "i");   
 
// 创建表达式 i > 5    
var con1 =    
Expression.Constant(5);   
var bin1 =    
Expression.GreaterThan(parameter, con1);   
 
// 创建表达式 i <= 7   
var con2 =    
Expression.Constant(7);   
var bin2 =    
Expression.LessThanOrEqual(parameter, con2);   
 
// 组合两个表达式   
var body =    
Expression.And(bin1, bin2);   
 
// 获取 Lambda 表达式   
var lambda =    
Expression.Lambda>(body, parameter);   
 
var _r = ints.Where(lambda.Compile());  

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

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


var ints =    
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };   
// var r =    
ints.Where(i => (i > 5 && i <= 7) || (i == 3));    
// 要实现的表达式   
 
// 创建参数 i   
var parameter =    
Expression.Parameter(typeof(int), "i");   
 
// 创建表达式 i > 5   
var con1 =    
Expression.Constant(5);   
var bin1 =    
Expression.GreaterThan(parameter, con1);   
 
// 创建表达式 i < 7   
var con2 =    
Expression.Constant(7);   
var bin2 =    
Expression.LessThanOrEqual(parameter, con2);   
 
// 创建表达式 i == 3   
var con3 =    
Expression.Constant(3);   
var bin3 =    
Expression.Equal(parameter, con3);   
 
// 组合 i > 5 && i <= 7   
var body =    
Expression.And(bin1, bin2);   
 
// 组合 ( i > 5 && i <= 7) OR (i == 3)   
body = Expression.Or(body, bin3);   
 
var lambda =    
Expression.Lambda>   
(body, parameter);   
var _r = ints.Where(lambda.Compile());  

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

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


var ints =    
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };   
//var r = ints.Select(i => i % 2 == 0 ? i : 0);    
// 要实现的表达式   
 
// 创建参数 i   
var parameter =    
Expression.Parameter(typeof(int), "i");   
 
// 创建表达式 i % 2   
var con1 =    
Expression.Constant(2);   
var bin1 =    
Expression.Modulo(parameter, con1);   
 
// 创建表达式 (i % 2) == 0   
var con2 =    
Expression.Constant(0);   
var bin2 =    
Expression.Equal(bin1, con2);   
 
// 创建表达式 IIF(((i % 2) = 0), i, 0)   
var bin3 =    
Expression.Condition   
(bin2, parameter, Expression.Constant(0));   
 
var lambda =    
Expression.Lambda>(bin3, parameter);   
var _r = ints.Select(lambda.Compile());  

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


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

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

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


你可能感兴趣的:(c#,c#,lambda,action,数据库,.net,语言)