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("\n");

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

FindListAnonymousMethod();

Console.Write("\n");

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}\t", 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}\t", 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}\t", str);

}

}

}

}

C#编程(四十三)----------Lambda表达式的更多相关文章

  1. Lambda01 编程范式、lambda表达式与匿名内部类、函数式接口、lambda表达式的写法

    1 编程范式 主要的编程范式有三种:命令式编程,声明式编程和函数式编程. 1.1 命令式编程 关注计算机执行的步骤,就是告诉计算机先做什么后做什么 1.2 声明式编程 表达程序的执行逻辑,就是告诉计算 ...

  2. python学习笔记四:lambda表达式和switch

    一.定义 lambda arg1,arg2... : returnValue 二.示例 #!/usr/bin/python def f(x,y): return x*y print f(2,3) g ...

  3. Kotlin基础(四)Lambda编程

    Lambda编程 一.Lambda表达式和成员引用 一)Lambda表达式语法 //注意与Java8中的区别 val sum={ x:Int,y:Int -> x+y } println(sum ...

  4. 十二、C# 委托与Lambda表达式(匿名方法的另一种写法)

    委托与Lambda表达式   1.委托概述 2.匿名方法 3.语句Lambda 4.表达式Lambda 5.表达式树   一.委托概述 相当于C++当中的方法指针,在C#中使用delegate 委托来 ...

  5. JAVA8之lambda表达式具体解释,及stream中的lambda使用

    前言: 本人也是学习lambda不久,可能有些地方描写叙述有误,还请大家谅解及指正! lambda表达式具体解释 一.问题 1.什么是lambda表达式? 2.lambda表达式用来干什么的? 3.l ...

  6. JAVA8之lambda表达式详解

    原文:http://blog.csdn.net/jinzhencs/article/details/50748202 lambda表达式详解 一.问题 1.什么是lambda表达式? 2.lambda ...

  7. 3分钟入门lambda表达式

    本节是lambda表达式的一个入门课,讲解的同时配有练习demo 前言什么是lambda表达式?基础语法函数式接口自己实现一个函数式接口jdk提供的函数式接口Consumersupplierfunct ...

  8. JDK新特性-Lambda表达式的神操作

    一.Lambda表达式的介绍 Lambda表达式是 Java8 中最重要的新功能之一.使用 Lambda 表达 式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看 起来更简洁易懂.Lambd ...

  9. 浅谈lambda表达式&lt;最通俗易懂的讲解

    Java8发布已经有一段时间了,这次发布的改动比较大,很多人将这次改动与Java5的升级相提并论.Java8其中一个很重要的新特性就是lambda表达式,允许我们将行为传到函数中.想想看,在Java8 ...

  10. Java语言与JVM中的Lambda表达式全解

    Lambda表达式是自Java SE 5引入泛型以来最重大的Java语言新特性,本文是2012年度最后一期Java Magazine中的一篇文章,它介绍了Lamdba的设计初衷,应用场景与基本语法. ...

随机推荐

  1. POJ 3666 Making the Grade(二维DP)

    题目链接:http://poj.org/problem?id=3666 题目大意:给出长度为n的整数数列,每次可以将一个数加1或者减1,最少要多少次可以将其变成单调不降或者单调不增(题目BUG,只能求 ...

  2. HDR 视频编码

    前转换以及后转换:-f xxx.cfg (以及注意工作目录以及路径名/和//) HEVC视频编码:-c xxx.cfg  -c xx.cfg(视频的配置文件)

  3. 第三届CCF软件能力认证

    1.门禁系统 问题描述 涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况.每位读者有一个编号,每条记录用读者的编号来表示.给出读者的来访记录,请问每一条记录中的读者是第几次出现. 输入格式 ...

  4. nginx log 错误502 upstream sent too big header while reading response header from upstream

    cookies的值超出了范围我是说 看看了一下日志 错误502 upstream sent too big header while reading response header from upst ...

  5. 使用Sublime Text 3的HTML-CSS-JS Prettify插件格式化代码

    很多时候,我们想要格式化HTML-CSS-JS代码,网站上有很多实现此功能的小工具,当然,我的网站首页也有.但是,如果我们的代码编辑器上面也有这样的功能,那不是更加快速便捷?So,接下来,我们看看Su ...

  6. bzoj 1143

    求最长反链裸题 补充一点知识.. 链                  :    D 中的一个子集 C   满足 C 是全序集  及C中所有元素都可以比较大小 反链              :   ...

  7. 007.MySQL-Keepalived搭配脚本01

    vim /etc/keepalived/check_MySQL.sh #!/bin/bash MYSQL=/usr/bin/mysql MYSQL_HOST=localhost MYSQL_USER= ...

  8. 006.LVM快照

    一 快照介绍 快照就是将当时的系统信息记录下来,就好像照相一样,未来若有任何资料变动了,则原始资料会被移动到快照区,没有被改动的区域则由快照区与档案系统共享. 二 快照原理 当建立快照区时,LVM会预 ...

  9. 005.SMB之user级别配置

    一 配置文件修改 注意: 1 share级别权限访问即,无需要用户名和密码才能访问. 2 新版samba4已取消share级别,可默认采用user级别. 1.1 全局配置文件修改 [global] w ...

  10. Orleans入门

    一.Grains 二.开发一个Grain 三.开发一个客户端 四.运行应用程序 五.调式 一.Grains Grains是Orleans编程模型的关键原语. Grains是Orleans应用程序的构建 ...