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

}

}

}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-22 02:55:11

C#高级编程四十三天----Lambda表达式的相关文章

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> fr

Java8函数式编程 (一) 数据流和lambda表达式

JDK 1.8中引入了函数式编程(functional programming,FP),如果您已习惯OOP,一定会感到困惑:什么是函数式编程?这样的编程模式有什么好处? 本文将通过简单的实例令读者对函数式编程有一个大体的了解. 我们知道OOP是以类为基础的,程序中必须首先抽象和定义class.那么FP创建的基础是什么?或者说在Java 8中,至少需要了解什么知识点才能实现基本的函数式编程呢? 本文将首先介绍在Java 8中使用FP所需的基本知识点: Lambda表达式 数据流 基本实例 Map<

Python笔记第3章,模块和模块的常用方法,函数式编程yield,三元运算Lambda表达式,内置涵数,常用模块

<--目录--> 模块和模块的常用方法 函数式编程 yield 三元运算 Lambda表达式 内置涵数 常用模块 [模块和模块的常用方法]至关重要的__init__.py    #包一定要有这个__init__.py文件,他才是包,这样才能通过form 包名 import 模块名(.py文件名)来去引用这个包的某个模块的某个函数功能 判断是否为主文件:__name__ if __name__ == '__main__' 当前文件路径: __file__ 当前文件描述: __doc__ 1)if

【Python笔记】Python的几个高级语法概念浅析:lambda表达式 &amp;&amp; 闭包 &amp;&amp; 装饰器

本文主要记录自己对几个高级语法概念的理解:匿名函数.lambda表达式.闭包.装饰器. 这几个概念并非Python特有,但本文只限于用Python做说明. 1. 匿名函数 匿名函数(anonymous function)是指未与任何标识符绑定的函数,多用在functional programming languages领域,典型应用场合: 1) 作为参数传给高阶函数(higher-order function ),如python中的built-in函数filter/map/reduce都是典型的

Java编程的逻辑 (91) - Lambda表达式

在之前的章节中,我们的讨论基本都是基于Java 7的,从本节开始,我们探讨Java 8的一些特性,主要内容包括: 传递行为代码 - Lambda表达式 函数式数据处理 - 流 组合式异步编程 - CompletableFuture 新的日期和时间API 本节,我们先讨论Lambda表达式,它是什么?有什么用呢? Lambda表达式是Java 8新引入的一种语法,是一种紧凑的传递代码的方式,它的名字来源于学术界的λ演算,具体我们就不探讨了. 理解Lambda表达式,我们先回顾一下接口.匿名内部类和

C#高级功能(一)Lambda 表达式

using System; namespace NewAttr { /// <summary> /// Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. /// Lambda 表达式对于编写 LINQ 查询表达式特别有用. /// </summary> public class LambdaDemo { public LambdaDemo() { } /// 委托不能重载,即委托名称相同,参数类型,个数不同. /// 构造委托的时候,根本不管参数,当然也就不知

C#高级编程六十五天----表达式树

表达式树 以前没听过表达式树,只听过表达式,而且听过Lambda表达式,首先介绍一下.NET里表达式树的核心概念:讲代码作为数据,他将一些代码表示为一个对象树,树中的每个节点本身都是一个表达式,不同的表达式类型代表能在代码中执行不同操作:二元操作,一元操作,方法调用等等. System.Linq.Expression命名空间包含了代表表达式的各个类.所有的表达式类都从Expression 类派生,Expresssion是个抽象类,主要包括的是一些静态方法,这些方法用于生成其他表达式类的实例.Ex

C#高级编程四十六天----正则表达式

正则表达式 1.定义一个Regex类的实例 Regex regex=new Regex(""); 这里初始化参数就是一个正则表达式,"\d"表示配置数字 2.判断是否匹配 判断一个字符串,是否匹配一个正则表达式,在Regex对象中,可以使用Regex.IsMatch(string )方法. Regex regex = new Regex(@"\d"); bool b1=regex.IsMatch("abc"); //返回值为f

【读书笔记】C#高级编程 第十三章 异步编程

(一)异步编程的重要性 使用异步编程,方法调用是在后台运行(通常在线程或任务的帮助下),并不会阻塞调用线程.有3中不同的异步编程模式:异步模式.基于事件的异步模式和新增加的基于任务的异步模式(TAP,可利用async和await关键字来实现). (二)异步模式 1.C#1的APM 异步编程模型(Asynchronous Programming Model). 2.C#2的EAP 基于事件的异步模式(Event-based Asynchronous Pattern). 3.TAP 基于任务的异步模