C# Lambda Expression概念浅析

开发 后端
C# Lambda Expressions是我们在开发过程中使用在数据删除操作时用到的,那么如果你是在学习LINQ to SQL的时候,那么建议你对C# Lambda Expressions还是要了解一下,以便操作的时候正确使用。

C# Lambda Expressions是什么呢?我们在处理数据库数据删除的操作的时候会碰到它,那么具体的C# Lambda Expressions是什么以及含义和使用是什么情况呢?那么下面我来看看具体的内容。

1.关于C# Lambda Expressions:

一个Lambda Expression  (译为Lambda式) 就是一个包含若干表达式和语句的匿名函数。可以被用作创建委托对象或表达式树类型。所有的Lambda式都使用操作符“=>“,表示“goes to (转变为)”。操作符左边部分是输入参数表,右边部分是表达式或语句块。x => x * x 读成“x转变为x 乘x”。Lambda式可以被赋值给一个委托类型:

C# Lambda实例1:

  1. delegate int del(int i);  
  2.  
  3. del myDelegate = x => x * x;  
  4.  
  5. int j = myDelegate(5); //j = 25  

也可以被用于创建一个表达式树类型:

C# Lambda实例2:

  1. using System.Linq.Expressions;  
  2.  
  3. //…  
  4.  
  5. Expression<del> = x => x *x;  

操作符“=>”具有和“=”一样的运算优先级,且为右相关(右边先执行)。

在例1中,我们注意到委托的定义中有一个int类型的输入参数以及int类型的返回值。例子中的Lambda式中并没有任何类型的声明。是编译器为我们做了相应的隐式数据类型转换:输入参数类型能够从委托的输入参数类型隐式转换,返回类型能够被隐式转换为委托的返回类型。

Lambda式不允许作为“is”和“as”操作符的左操作数出现。也就是

  1. del myDelegate = x => x * x as string;  //error 

所有对于匿名方法的约束也同样适用于Lambda式。请参阅Anonymous Methods (C# Programming Guide).

2.从表达式理解C# Lambda Expressions

由一个计算表达式组成的一个Lambda式称之为表达式Lambda。表达式Lambda常被用于构造表达式树。一个表达式Lambda返回计算表达式运算的结果。基本结构如下:

  1. (input parameters) => expression  
  2.  
  3. //如果只有一个输入参数时,括号可以省略。  
  4.  
  5. //如果具有一个以上的输入参数,必需加上括号。  
  6.  
  7. (x) => x * x 等于 x => x * x  
  8.  
  9. (x, y) => x == y  
  10.  
  11. //可以显式指定输入参数的类型  
  12.  
  13. (int x, string s) => s.Length > x  
  14.  
  15. //也可以没有任何输入参数  
  16.  
  17. () => SomeMethod1()  

上面这段代码在Lambda式中调用了一个方法。需要注意的是,如果在创建会被其他方使用的表达式树的时候,不宜在Lambda式中执行方法调用。比如:在SQL Server内执行。

一般来说,让一个方法在原先设计的上下文环境以外执行没有意义,也不能真正工作。

3.从语句理解C# Lambda Expressions

语句Lambda和表达式Lambda非常相似,只是语句被包含在大括号内:

  1. (input parameters) => {statement;} 

大括号中的语句可以是任意多条,也可以写成多行(定义一个Lambda式也就是在定义一个匿名方法):

  1. TestDelegate myDel = n => { string s = n + " " + "World";   
  2.  
  3. Console.WriteLine(s); };  

当然语句Lambda跟匿名方法一样,无法用于创建表达式树。

4.C# Lambda Expressions之类型猜测

当编写一个Lambda式的时候,我们通常不需要明确指定输入参数的类型。因为编译器会根据Lambda体的实现,以及委托的定义来猜测类型。

举例:如果要从一个List<int>中删除小于100的元素

  1. lst.RemoveAll(i => i < 100);   //i会被猜测为int 

通常的猜测规则如下

◆Lambda式必须包含与委托定义中相等数量的输入参数;

◆每个Lambda式的输入参数必须能够隐式转换成委托定义中所要求的输入参数;

◆Lambda式的返回值必须能够隐式转换成委托定义中的返回值。

注意:由于目前在common type system中还没有一个“Lambda式类型”的类型。如果在有些场合提到“Lambda式的类型”,那通常表示委托的定义或者是Expression<>类型。

5.C# Lambda Expressions变量作用域

在Lambda式定义中可以引用外部变量。只要是在定义处能够访问到的变量,都可以在Lambda式中引用。

Lambda式的定义仅仅是定义一个匿名方法,最终会生成一个委托对象。外部变量的引用将被“捕获”到委托对象内部,将会伴随委托对象的整个生命周期。在委托对象生命周期结束之前该变量都不会被垃圾回收。就算外部变量已经超过了原来的作用域,也还能继续在Lambda式中使用。所有会被引用的外部变量必须在Lambda式定义之前被显式赋值。见下例

  1. delegate bool D();  
  2. delegate bool D2(int i);  
  3. class Test  
  4. {  
  5. D del;  
  6. D2 del2;  
  7. public void TestMethod(int input)  
  8. {  
  9. int j = 0;  
  10. // Initialize the delegates with lambda expressions.  
  11. // Note access to 2 outer variables.  
  12. // del will be invoked within this method.  
  13. del = () => { j = 10;  return j > input; };  
  14.  
  15. // del2 will be invoked after TestMethod goes out of scope.  
  16. del2 = (x) => {return x == j; };  
  17. // Demonstrate value of j:  
  18. // Output: j = 0   
  19. // The delegate has not been invoked yet.  
  20. Console.WriteLine("j = {0}", j);  
  21. // Invoke the delegate.  
  22. bool boolResult = del();  
  23. // Output: j = 10 b = True //注意j在del的执行过程中被修改  
  24. Console.WriteLine("j = {0}. b = {1}", j, boolResult);  
  25. }  
  26. static void Main()  
  27. {  
  28. Test test = new Test();  
  29. test.TestMethod(5);  
  30. // Prove that del2 still has a copy of  
  31. // local variable j from TestMethod.   
  32.  
  33. //j的引用超出了原先定义的作用域  
  34. bool result = test.del2(10);  
  35. // Output: True  
  36. Console.WriteLine(result);  
  37. Console.ReadKey();  
  38. }  
  39. }  
  40.  

下面是关于变量作用域的规则:

◆被“捕获”的变量在委托的生命周期结束前都不会被垃圾回收;

◆在Lambda式内部定义的变量对外不可见;

◆Lambda式无法直接捕获一个具有ref或out描述的参数变量;

◆Lambda式中的return语句不会导致当前所在的方法返回;

◆Lambda式中不允许包含会导致跳当前执行范围的goto,break 或 continue语句。

6.C# Lambda Expressions学习的总结

Lambda式可以说就是另外一种形式的匿名方法。用在某些地方,会使代码更加简洁。定义一个Lambda式本质上就是定义一个委托的实现体。

原文来自博客园:http://www.cnblogs.com/smwikipedia/archive/2009/05/06/1450825.html

C# Lambda Expressions的相关内容就向你介绍到这里,希望对你了解和学习掌握C# Lambda Expressions有所帮助,之后我们会继续学习C# Lambda Expressions的一些应用。

【编辑推荐】

  1. LINQ to SQL删除实现浅析
  2. LINQ to SQL删除实现体会小结
  3. LINQ删除记录的操作实现
  4. 实现LINQ删除数据的巧妙方法
  5. 详解实现LINQ to SQL删除行
责任编辑:仲衡 来源: 博客园
相关推荐

2009-09-14 14:25:53

C# Lambda EC# Lambda

2009-09-02 10:58:02

C#动态数组

2009-08-27 17:11:44

C# Fluent I

2009-09-09 16:46:59

C# XmlSeria

2009-08-26 14:16:17

C# FrameWor

2009-08-18 09:51:18

C#枚举类型

2009-08-20 18:47:19

C#异步通信

2009-09-09 10:47:29

C# CheckBox

2009-09-11 11:16:53

C# Attribut

2009-08-24 17:39:21

C# 泛型集合

2009-08-21 14:47:39

C#网络编程

2009-08-24 15:28:19

C# 泛型方法

2009-09-02 13:41:57

C#字符串操作

2009-09-01 16:10:28

C#单元测试

2009-08-07 17:25:37

C# SortedLi

2009-08-17 18:34:50

C# ChangeCo

2009-08-14 17:45:52

C# ArrayLis

2009-08-25 17:59:49

C#入门

2009-08-24 14:26:42

C# 泛型类

2009-08-27 13:30:11

C# interfac
点赞
收藏

51CTO技术栈公众号