zoukankan      html  css  js  c++  java
  • 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); 

                } 

            } 

        } 

    }

  • 相关阅读:
    HDU4474 Yet Another Multiple Problem BFS搜索
    HDU4473 Exam 数学分析
    2013ACM多校联合(4)
    POJ1273 网络流...
    HDU4472 Count 递推
    POJ1149 PIGS 网络流
    UVA10881 Piotr's Ants 想法题
    javascript js string.Format()收集
    修改 设置 vs.net 网站 调试 设为 起始页
    【转】HTML5杂谈 概念与现行游戏 割绳子 宝石迷阵
  • 原文地址:https://www.cnblogs.com/FinleyJiang/p/7602625.html
Copyright © 2011-2022 走看看