• C#编程(四十三)----------Lambda表达式


    Lambda表达式

    案例:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    namespace lambda表达式

    {

        class Program

        {

            public delegate int del(int i);

            static void Main(string[] args)

            {

                List<string> fruits = new List<string> { "apple", "orange", "blueberry", "passionfruit" };

                IEnumerable<string> query = fruits.Where(fruit => fruit.Length <6);

                foreach (string fruit in query)

                {

                    Console.WriteLine(fruit);

                }

                Console.ReadKey();

            }

        }

    }

    输出结果是:apple

    一般where都是跟Lambda表达式一起使用的,where语法包含在Linq命名空间下,何为Lambda表达式呢,简单地说就是匿名函数,也跟委托匿名差不多

    案例:

    class Program

        {

            //声明委托类型

            public delegate int del(int i);

            static void Main(string[] args)

            {

                //定义一个委托事件

                del MyDelegate = x => x * 6;

                int j = MyDelegate(5);

                Console.WriteLine(j);

                Console.ReadKey();

            }

    }

    输出:30

    估计很容易看明白.

    Lambda表达式规则:

    表达式位于=>运算符的右侧(input parameters)=>expression

    Lambda只有一个输入参数的时候,括号才是可选的,否则括号是必须的.

    例如:(x,y)=>x==y

    有时当编译器无法判断类型的时候,出现这种情况,你可以显示指定参数类型.

    例如:(int x,string y)=>s.length>x

    当使用空括号表示指定0个参数

    例如:()=SomeMethod();

    案例:

    class Program

        {

            //声明委托类型

            public delegate void ShowStr(string s);

            static void Main(string[] args)

            {

                //定义一个委托事件

                ShowStr myshow = n => { string s = n + " " + "world"; Console.WriteLine(s); };

                myshow("hello");

                Console.ReadKey();

            }

    }

    输出: hello world

    分析:Lambda符号左侧是参数

    其实理解了委托和实践就很容易理解Lambda,说白了就是匿名委托,再进一步直白一点就是匿名函数.

    稍微复杂一点的Lambda表达式

    static void Main(string[] args)

            {

                //表达式的声明

                Func<int, bool> myFunc = x => x == 5;

                bool res = myFunc(4);//这里传递5就是true

                Console.WriteLine(res);

                Console.ReadKey();

            }

    分析:上面声明的表达式,是以int类型作为参数,然后做一个比较,返回的是一个bool.

    如果参数是Expression<Func>,你也可以提供Lambda表达式,例如在System.Linq.Queryable内定义的标准查询运算符中.如果指定Expression<Func>参数,lambda将编译为表达式的目录树.

    下例显示了一个标准查询运算符

            static void Main(string[] args)

            {

                //表达式的声明

                int[] array = {1,2,3,4,5,6,7,8,9 };

                int oddNumbers = array.Count(n => n % 2 == 1);

                Console.WriteLine(oddNumbers);

                Console.ReadKey();

            }

    分析:该例的作用是用来计算数组中奇数的个数

    案例:

    class Program

        {       

            static void Main(string[] args)

            {

                //表达式的声明

                int[] array = {1,2,3,4,5,6,7,8,9 };

                //计算出小于6左侧的数字

                var firstNumberLessThan6 = array.TakeWhile(n => n < 6);

                Console.WriteLine("一直输出,遇到大于6的数就停止");

                foreach (var item in firstNumberLessThan6)

                {

                    Console.WriteLine(item + " "); ;

                }

                var firstSmallNumbers = array.TakeWhile((n, index) => n >= index);

                Console.WriteLine("输出索引小于值的数");

                foreach (var item in firstSmallNumbers)

                {

                    Console.WriteLine(item+" ");

                }            

                Console.ReadKey();

            }

    }

    所有Lambda表达式都使用Lambda运算符=>,该运算符读作”goes to”.Lambda运算符的左边是输入参数(如果有),右边是表达式或语句块.Lambda表达式x=>x*x读作”x goes to x times x”.可以将此表达式分配给委托类型,如下所示:

    delegate int del (int i);

    del MyDelagate=x=>x*x;

    int j=MyDelegate(5);

    Console.WriteLine(j);//j=5

    Lambda表达式在一定程度上就是匿名方法的另一种表现形式.为了方便对Lambda表达式的解释,首先需要创建一个People.代码如下:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Threading;

    using System.Threading.Tasks;

    namespace ConsoleApplication1

    {

        class Program

        {

            static void Main(string[] args)

            {

                //使用list创建一个对象的集合

                List<People> people = new List<People>();

                People p1 = new People(21,"sunwukong");

                People p2 = new People(22, "zhubajie");

                People p3 = new People(23, "shaheshang");

                People p4 = new People(24, "tangsen");

                people.Add(p1);

                people.Add(p2);

                people.Add(p3);

                people.Add(p4);

                //筛选年龄超过22的人,通过IEnumerable接口创建一个results集合,并且该集合中填充的是年龄大于22

                //People对象.这里使用了一个匿名方法进行筛选,因为该方法没有名称,通过私用People

                //类对象的age字段进行筛选

                //IEnumerable<People> results=people.Where(delegate(People p){return p.age>22;})

                /*

                 * 虽然上述代码也实现了筛选操作,但是使用匿名方法往往不太容易理解和阅读,Lambda表达式则更加理解和阅读

                 * 该代码同样返回了People对象的集合给变量results,但是编写的方法更加容易.

                 * 其实,Lambda表达式在编写上和匿名方法很相似,当编译器开始编译并运行时,Lambda表达式最终也表现为匿名方法.

                 */

                IEnumerable<People> results = people.Where(People => People.age > 22); 

                

            }

        }

        /// <summary>

        /// 一个People,并包含一个默认的构造函数能够为People对象

        /// 进行年龄和姓名的初始化.

        /// </summary>

        public class People

        {

            public int age { get; set; }

            public string name { get; set; }

            public People(int age, string name)

            {

                this.age = age;

                this.name = name;

            }

        }

    }

    分析:使用匿名方法并不是创建没有名称的方法,实际上编译器会创建一个方法,这个方法对于开发人员来说是不可见的,该方法会将People类的对象中符合p.age>22的对象返回并填充到集合中,相同的,使用Lambda表达式,当编译器编译时,Lambda表达式同样会被编译成一个匿名方法进行相应的操作,但是与匿名方法相比,Lambda表达式更容易阅读,Lambda表达式的格式如下:

    (参数列表)=>表达式或语句块

    上述代码中,参数列表是People,表达式或语句块就是People.age>20,使用Lambda表达式能够让人很容易的理解该语句究竟是如何执行的,虽然匿名方法提供了同样的功能,去不容易被理解,相比之下,People=>People.age>22却能很好的的理解为”返回一个年龄大于22的人”.其实,Lambda并没有什么高神的技术,Lambda表达式可以看做是匿名方法的另一种表达形式.

    Lambda表达式可以有多个参数,一个参数,或者没有参数,七参数类型可以是隐式或者显式.示例如下:

    (x,y)=>x*y //多参数,隐式类型=>表达式

    x=>x*5 //单参数,隐式类型=>表达式

    x=>{ return x*5; } //单参数,隐式类型=>语句块

    (int x)=>x*5 //单参数,显示类型=>表达式

    (int x)=>{return x*5;} //单参数,显式类型=>语句块

    ()=>Console.WriteLine() //无参数

    上述格式都是Lambda表达式的合法格式,在编写Lambda表达式时,可以忽略参数的类型,因为编译器能够根据上下文直接推断参数的类型,案例:

    (x,y)=>x+y //多参数,隐式类型=>表达式

    Lambda表达式的主题可以是表达式也可以是语句块,这样就节约了代码的编写.

    案例:使用传统代码,匿名方法和Lambda表达式对比.

    using System;  

    using System.Collections.Generic;  

    using System.Linq;  

    using System.Text;  

    namespace LambdaDemo  

    {  

        class Program  

        {  

            static void Main(string[] args)  

            {  

                Console.WriteLine("传统的委托代码示例:");  

                FindListDelegate();  

                Console.Write(" ");  

                Console.WriteLine("使用匿名方法的示例:");  

                FindListAnonymousMethod();  

                Console.Write(" ");  

                Console.WriteLine("使用Lambda的示例:");  

                FindListLambdaExpression();  

            }  

            //传统的调用委托的示例  

            static void FindListDelegate()  

            {  

                //先创建一个泛型的List类  

                List<string> list = new List<string>();  

             list.AddRange(new string[] { "ASP.NET课程","J2EE课程", "PHP课程", "数据结构课程" });  

                Predicate<string> findPredicate = new Predicate<string>(IsBookCategory);  

                List<string> bookCategory = list.FindAll(findPredicate);  

                foreach (string str in bookCategory)  

                {  

                    Console.WriteLine("{0} ", str);  

                }  

            }  

            //谓词方法,这个方法将被传递给FindAll方法进行书书籍分类的判断  

            static bool IsBookCategory(string str)  

            {  

                return str.EndsWith("课程") ? true : false;  

            }  

            //使用匿名方法来进行搜索过程  

            static void FindListAnonymousMethod()  

            {  

                //先创建一个泛型的List类  

                List<string> list = new List<string>();  

             list.AddRange(new string[] { "ASP.Net课程", "J2EE课程", "PHP课程", "数据结构课程" });  

                //在这里,使用匿名方法直接为委托创建一个代码块,而不用去创建单独的方法  

                List<string> bookCategory = list.FindAll  

                    (delegate(string str)  

                    {  

                        return str.EndsWith("课程") ? true : false;  

                    }  

                    );  

                foreach (string str in bookCategory)  

                {  

                    Console.WriteLine("{0} ", str);  

                }  

            }  

            //使用Lambda来实现搜索过程  

            static void FindListLambdaExpression()  

            {  

                //先创建一个泛型的List类  

                List<string> list = new List<string>();  

             list.AddRange(new string[] { "ASP.NET课程", "J2EE课程", "PHP课程", "数据结构课程" });  

                //在这里,使用了Lambda来创建一个委托方法  

                List<string> bookCategory = list.FindAll((string str) => str.EndsWith("课程"));  

                foreach (string str in bookCategory)  

                {  

                    Console.WriteLine("{0} ", str);  

                }  

            }  

        }  

     

  • 相关阅读:
    遍历一个枚举类型
    ASP.NET:C#中时间格式的转换
    DataAdapter去批量更新数据的FAQ
    .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (第2版) (C# DIY HttpWebClient) 收藏
    如何使数据库中取出的数据保持原有格式
    如何获取控制台应用程序自己的文件名
    2008将倒掉一大部分的工厂和贸易公司
    组六对半分组组合投资方案(36789)
    重又归孑然一身
    善于总结
  • 原文地址:https://www.cnblogs.com/android-blogs/p/6603544.html
Copyright © 2020-2023  润新知