什么是Lambda 表达式?

    "Lambda表达式"实际上是一个方法,只不过该方法是一个匿名方法(就是没有名字的方法(函数),就是说只有在定义的时候能调用,在其他地方就不能调用了),是一种高效的类似于函数式编程的表达式,  (@高效 : 只在一个地方用用完就不用了,没必要单独写一个方法) 所有Lambda表达式都使用Lambda运算符 =>; ,该运算符读作"goes to"。该标记在 lambda 表达式中用来将左侧的输入变量与右侧的 lambda 体分离。 Lambda 表达式是与匿名方法类似的内联表达式,但更加灵活;在以方法语法表示的 LINQ 查询中广泛使用了 Lambda 表达式。

  注:带 @ 为个人查资料理解。

Lambda 预备知识

   1 . Enumerable 类

    说明 :提供一组用于查询实现 System.Collections.Generic.IEnumerable<T>(泛型集合) 的对象的 static方法。

我们平常最常用Lambda的地方是对集合的操作。所以我们要首先简要列举一下此类以及常用方法,在使用中详细介绍。

     Where :  基于谓词筛选值序列。

      Select  : 将序列中的每个元素投影到新表中

     SelectMany : 将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。

     Single<TSource> : 返回序列的唯一元素;如果该序列并非恰好包含一个元素,则会引发异常.

     Skip<TSource> : 跳过序列中指定数量的元素,然后返回剩余的元素。

     SkipWhile<TSource> : 只要满足指定的条件,就跳过序列中的元素,然后返回剩余元素。

     Sum : 计算 Int32 值序列之和。

     Take<TSource> : 从序列的开头返回指定数量的连续元素。

     TakeWhile<TSource> : 只要满足指定的条件,就会返回序列的元素。

     。。。。。。。。。。。

  2 . Func<T, TResult>

    由于上面介绍的方法中很多都涉及到一个参数Func<TSource,TResult>. 鉴于很多小伙伴不太理解这个(我也不太理解),咱就一起探讨下。

    Func<T,TR> 定义 :封装一个具有一个参数并返回 TResult 参数指定的类型值的方法。

    这个函数是一个委托(引用类型) public delegate TResult Func<in T, out TResult>(T arg); 共有17个重载

        in T

        此委托封装的方法的参数类型。

     out TResult

        此委托封装的方法的返回值类型。

 class Class1
{
    
Func<string, string> fc = new Func<string, string>(GetName); public void WriteName()
{
fc.Invoke("吐鲁番");
} public static string GetName(string s)
{
return s;
}
}

  看一下我们平时用的Where方法 Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)
 
   List<User> userLists = new List<User>() {
new User(){ Name = "罗生天" ,PassWord="123456"},
new User(){ Name = "吉祥天" ,PassWord="123456"},
new User(){ Name = "灵宝天" ,PassWord="123456"},
new User(){ Name = "红尘天" ,PassWord="123456"},
new User(){ Name = "魔刹天" ,PassWord="123456"},
}; var user = userLists.Where(p => p.Name=="罗生天"); var user2 = userLists.Where(delegate(User p)
{
return p.Name == "罗生天";
});
  为什么我们平时传参传的是lambda表达式呢 看下面这个例子:
  先看下这条语句  Func<int, bool> d = x => x == 10 ? true : false ; 为什么 可以写成这种形式呢 ? 
  答: 请注意委托签名具有一个 int 类型的隐式类型输入参数,并返回bool。可以将 Lambda 表达式转换为该类型的委托,因为该表达式也具有一个输入参数 (x),以及一个编译器可隐式转换为 bool 类型的返回值。(百度百科)。
这就是我们平时为什么这样写了

Lambda使用注意事项

    在 is 或 as 运算符的左侧不允许使用 Lambda。

    适用于匿名方法的所有限制也适用于 Lambda 表达式。有关更多信息,请参见匿名方法(C# 编程指南)。
    特殊
    下列规则适用于 Lambda 表达式中的变量范围:捕获的变量将不会被作为垃圾回收,直至引用变量的委托超出范围为止。
    在外部方法中看不到 Lambda 表达式内引入的变量。
    Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
      Lambda 表达式中的返回语句不会导致封闭方法返回。
    Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。
    Lambda表达式的本质是“匿名方法”,即当编译我们的程序代码时,“编译器”会自动将“Lambda表达式”转换为“匿名方法”,如下例:
    string[] names={"agen","balen","coure","apple"};
string[] findNameA=Array.FindAll<string>(names,delegate(string v){return v.StartsWith("a");});
string[] findNameB=Array.FindAll<string>(names,v=>v.StartsWith("a"));

    上面中两个FindAll方法的反编译代码如下:  

    string[]findNameA=Array.FindAll<string>(names,delegate(stringv){returnv.StartsWith("a");});
    string[]findNameB=Array.FindAll<string>(names,delegate(stringv){returnv.StartsWith("a");});

从而可以知道“Lambda表达式”与“匿名方法”是可以划上等号的,只不过使用“Lambda表达式”输写代码看上去更直观漂亮,不是吗?

Lambda表达式使用

1. 输入参数 ( "=>"运算符 左边 )和表达式或语句块( "=>"运算符 右边 )  

输入参数 即 " => " 左边部分 。它包含的参数数量可以 为0 ,1 或者多个。当输入参数个数 是1 时 ,表达式左边的小括号 可以省略 ,其他必须加括号 。

   输入参数 数量 大于或者等于 2 时,表达式 左边的小括号 用 "," 分开

(x, y) => x == y

有时,编译器难以或无法推断输入类型。 如果出现这种情况,你可以按以下示例中所示方式显式指定类型:

(int x, string s) => s.Length > x

  没有参数

() => SomeMethod()

2. 与Enumerable 类 结合使用

 List<User> userLists = new List<User>() {
new User(){ Name = "罗生天" ,PassWord=""},
new User(){ Name = "吉祥天" ,PassWord=""},
new User(){ Name = "灵宝天" ,PassWord=""},
new User(){ Name = "红尘天" ,PassWord=""},
new User(){ Name = "魔刹天" ,PassWord=""},
new User(){ Name = "清虚天" ,PassWord=""},
};

(1)Where方法   Func<TSource, Boolean>用于测试每个元素是否满足条件的函数,返回值是bool类型。 相当于 if (x > y) 即筛选条件 ;

Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)

var user = userLists.Where(p => p.Name=="罗生天");

这种写法是 当调用Where方法时TSource已经确定 返回值也已经确定IEnumerable<User> 。(?)

Where<TSource>(IEnumerable<TSource>, Func<TSource, Int32, Boolean>)

var otherUser = userLists.Where<User>((p,m) => p.Name.Length > m);

第二个参数为该元素的索引。

 (2) Select方法 将序列中的每个元素投影到新表中。与Where一样有两个重载 第二个参数 是索引。通俗来说就是 把集合中的元素 的某些属性 拿出来 。

Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>)

      List<string> strs = new List<string>() { "","2adfs",""};
var caste = strs.Select<string,string>(st =>
{
if (st.Length > )
st = "";
return st;
});
           var names = userLists.Select(p => p.Name); // 取每个元素中的 "Name" 返回值为IEnumerable<string>

            var newList = userLists.Select(p => new Student()
{
Name = p.Name,
Grade =Convert.ToInt32( p.PassWord)
}); // 得到新类型的集合 此时的返回值为IEnumerable<Student>

(3)TakeWhile 实例  与Where 不同点是 当找到匹配的元素时就会返回  一个 IEnumerable<T>,包含输入序列中出现在测试不再能够通过的元素   (未匹配)之前的元素。

string[] fruits = { "apple", "banana", "mango", "orange",
"passionfruit", "grape" }; IEnumerable<string> query =
fruits.TakeWhile(fruit => String.Compare("orange", fruit, true) != ); foreach (string fruit in query)
{
Console.WriteLine(fruit);
} /*
This code produces the following output: apple
banana
mango
*/

暂时先到这了 最常用的也就是Where跟Select了。 虽然还有好多东西没介绍不过大概都差不多。大家可以自己多了解下其他的 ,第一次写博客 文章难免会有漏洞 或者不对的地方 ,希望大家能指出来 一起讨论 一起学习 ,一起进步 。祝大家早日 升职加薪, 当上总经理, 出任CEO, 迎娶白富美, 走上人生巅峰。

  

C# Lambda表达式 基础的更多相关文章

  1. Linq To sql入门练习 Lambda表达式基础

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. Lambda表达式基础

    1.委托的典型用法 1.1定义一个委托: public delegate int AddDelegate(int i, int j); 1.2 定义一个MyClass类,放置一个满足 AddDeleg ...

  3. 【Java8新特性】Lambda表达式基础语法,都在这儿了!!

    写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...

  4. Java中Lambda表达式基础及使用详解

    概述 Lambda 是JDK 8 的重要新特性.它允许把函数作为一个方法的参数(函数作为参数传递进方法中),使用 Lambda 表达式可以使代码变的更加简洁紧凑,使Java代码更加优雅. 标准格式 三 ...

  5. Java8之Lambda表达式基础

    Java 8中,将会提供对lambda的支持,函数式编程FP(Functional Programming)将会得到很好地支持,而函数式编程的一个重要特点就是适合并行运算. λ:希腊字母表中排序第十一 ...

  6. java8 Lambda表达式的新手上车指南(1)--基础语法和函数式接口

    背景 java9的一再推迟发布,似乎让我们恍然想起离发布java8已经过去了三年之久,java8应该算的上java语言在历代版本中变化最大的一个版本了,最大的新特性应该算得上是增加了lambda表达式 ...

  7. 初探Lambda表达式/Java多核编程【3】Lambda语法与作用域

    接上一篇:初探Lambda表达式/Java多核编程[2]并行与组合行为 本节是第二章开篇,前一章已经浅显地将所有新概念点到,书中剩下的部分将对这些概念做一个基础知识的补充与深入探讨实践. 本章将介绍L ...

  8. java8 Lambda表达式的新手上车指南(1)

    背景 java9的一再推迟发布,似乎让我们恍然想起离发布java8已经过去了三年之久,java8应该算的上java语言在历代版本中变化最大的一个版本了,最大的新特性应该算得上是增加了lambda表达式 ...

  9. 4.3 lambda表达式

    函数,封装的代码块可以很复杂,也可以很简单.当函数的代码块简单到只有一个表达式,就可以考虑用lambda表达式,也称匿名函数. 1 lambda表达式基础 #首先需要声明一点:lambda是表达式而非 ...

随机推荐

  1. 处理QMenu的triggered信号时遇到的一个问题

    最近,在一个Qt程序中使用QMenu类时,遇到了一个小问题,特记录下.首先,我模仿一下问题出现的场景:假设我在做一个高大上的XX管理系统,比如说:学生信息管理系统.在这个系统中,学生的各项信息(比如: ...

  2. 【洛谷】2607: [ZJOI2008]骑士【树形DP】【基环树】

    P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...

  3. Express中间件

    一.编写中间件 中间件函数能够访问请求对象(req),响应对象(res),应用程序的请求/响应循环中的下一个中间件函数.下一个中间件函数通常由名为next的变量来表示. 中间件函数可以执行以下任务: ...

  4. Codeforces Round #293 (Div. 2) C. Anya and Smartphone 数学题

    C. Anya and Smartphone time limit per test 1 second memory limit per test 256 megabytes input standa ...

  5. python中的__all__和__slots__

    python两个有趣属性__all__可用于模块导入时限制,如:from module import *此时被导入模块若定义了__all__属性,则只有all内指定的属性.方法.类可被导入~若没定义, ...

  6. Syncovery 是目前功能最为强大的实时自动备份工具

    Syncovery Pro(原名叫做Super Flexible Synchronizer) 是目前功能最为强大的实时自动备份工具,连FTP.WebDAV等全部支持! 最近从V6开始改用比较好记.易懂 ...

  7. 6. python 字符串格式化表达式

    6. python 字符串格式化表达式 字符串格式化允许在一个单个的步骤中对一个字符串执行多个特定类型的替换 特别是给用户提示的时候,格式化非常方便 实现方法: 1.格式化表达式,类似于c语言的pri ...

  8. [Oracle] Insert All的妙用

    无条件的插入 Oracle中的insert all是指把同一批数据插入到不同的表中,假如如今有个需求:把t表中的数据分别插入t1,t2,假设你不知道insert all,你可能会使用insert插入2 ...

  9. CAS工作流程

    CAS3.0的工作流程: 0.app将用户转发到CAS处, 并将自己的url作为callback参数传给CAS. 1.CAS验证用户成功(authentication) 2.生成用户实体(princi ...

  10. (转)SQL Server 列转行

    原文:http://www.myexception.cn/sql-server/1078985.html1,2,3,4,5以上是一个字符串或则一逗号分隔的数字. 这里希望用一条语句查询出这样的效果: ...