热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#Lambda表达式基础

什么是Lambda表达式?Lambda表达式实际上是一个方法,只不过该方法是一个匿名方法(就是没有名字的方法(函数),就是说只有在定义的时候能调用,在其他地方就不能调用了),是一种高

什么是Lambda 表达式?

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

lambda expressions to separate the input variables on the left side from the lambda body on the right side.">  注:带 @ 为个人查资料理解。

lambda expressions to separate the input variables on the left side from the lambda body on the right side.">lambda expressions to separate the input variables on the left side from the lambda body on the right side.">Lambda 预备知识

    lambda expressions to separate the input variables on the left side from the lambda body on the right side.">1 . Enumerable 类 

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

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

     Where基于谓词筛选值序列。

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

     SelectMany : IEnumerable> and flattens the resulting sequences into one sequence.">将序列的每个元素投影到 IEnumerable 并将结果序列合并为一个序列。

IEnumerable> and flattens the resulting sequences into one sequence.">     Single返回序列的唯一元素;如果该序列并非恰好包含一个元素,则会引发异常.

IEnumerable> and flattens the resulting sequences into one sequence.">     Skip跳过序列中指定数量的元素,然后返回剩余的元素。

IEnumerable> and flattens the resulting sequences into one sequence.">     SkipWhile只要满足指定的条件,就跳过序列中的元素,然后返回剩余元素。

IEnumerable> and flattens the resulting sequences into one sequence.">     Sum : Int32 values.">计算 Int32 值序列之和。

IEnumerable> and flattens the resulting sequences into one sequence.">Int32 values.">     Take从序列的开头返回指定数量的连续元素。

IEnumerable> and flattens the resulting sequences into one sequence.">Int32 values.">     TakeWhile只要满足指定的条件,就会返回序列的元素。

IEnumerable> and flattens the resulting sequences into one sequence.">Int32 values.">     。。。。。。。。。。。

  2 . Func<T, TResult> lambda expressions to separate the input variables on the left side from the lambda body on the right side.">

lambda expressions to separate the input variables on the left side from the lambda body on the right side.">    由于上面介绍的方法中很多都涉及到一个参数Func. 鉴于很多小伙伴不太理解这个(我也不太理解),咱就一起探讨下。

lambda expressions to separate the input variables on the left side from the lambda body on the right side.">    Func 定义 :TResult parameter.">封装一个具有一个参数并返回 TResult 参数指定的类型值的方法

lambda expressions to separate the input variables on the left side from the lambda body on the right side.">TResult parameter.">    这个函数是一个委托(引用类型) public delegate TResult Func(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(IEnumerable, Func)
 
   List userLists = new List() { 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<intbool> d = x => x == 10 ? true : false ; 为什么 可以写成这种形式呢 ? 
  答: 请注意委托签名具有一个 int 类型的隐式类型输入参数,并返回bool。可以将 Lambda 表达式转换为该类型的委托,因为该表达式也具有一个输入参数 (x),以及一个编译器可隐式转换为 bool 类型的返回值。(百度百科)。
这就是我们平时为什么这样写了

Lambda使用注意事项

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

    适用于 匿名方法的所有限制也适用于 Lambda 表达式。有关更多信息,请参见匿名方法(C# 编程指南)。
     特殊
lambda expressions to separate the input variables on the left side from the lambda body on the right side.">    下列规则适用于 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 expressions to separate the input variables on the left side from the lambda body on the right side.">Lambda表达式使用 

 1. 输入参数 ( "=>"运算符 左边 )和=>, and you put the expression or statement block on the other side.">表达式或语句块( "=>"运算符 右边 )  

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

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

(x, y) => x == y

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

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

  没有参数

() => SomeMethod()

 

2. 与Enumerable 类 结合使用

 List userLists = new List() {
                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"},
                new User(){ Name = "清虚天" ,PassWord="123456"},
            };

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

 Where(IEnumerable, Func)

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

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

Where(IEnumerable, Func)

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

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

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

 Select(IEnumerable, Func)

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

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

 (3)TakeWhile 实例  与Where 不同点是 当找到匹配的元素时就会返回  IEnumerable> that contains the elements from the input sequence that occur before the element at which the test no longer passes.">一个 IEnumerable,包含输入序列中出现在测试不再能够通过的元素   (未匹配)之前的元素。

string[] fruits = { "apple", "banana", "mango", "orange", 
                                  "passionfruit", "grape" };

            IEnumerable<string> query =
                fruits.TakeWhile(fruit => String.Compare("orange", fruit, true) != 0);

            foreach (string fruit in query)
            {
                Console.WriteLine(fruit);
            }

            /*
             This code produces the following output:

             apple
             banana
             mango
            */

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

  

 


推荐阅读
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
author-avatar
未知的明天
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有