一个C#中的例子——lambda表达式

保姆级教程:用PROGRAM_FTDI搞定Xilinx FPGA的JTAG调试器(基于FT232/FT2232/FT4232) 本文详细介绍了如何使用FT232/FT2232/FT4232系列芯片通过PROGRAM_FTDI工具配置Xilinx FPGA的JTAG调试器。从芯片选型、驱动安装到固件烧写和Vivado验证,提供了完整的实操指南和避坑要点,帮助开发者低成本实现高效调试。 阅读详情

我们多次提到,当前来说,Web开发领域,开发工具(或者叫平台)的“三巨头”是 .Net、JAVA和PHP。如果用.Net,那么一般用C#语言(或者VB),在C#语言3.0版中,引入了一个非常重要的新特性称为“lambda表 达式”。首先来普及一下“lambda表达式”的概念和作用。lambda 是一个希腊字母“λ”的英文读音,我们中国人一般念作“拉姆达”。

首先,在C#中,可以用 lambda表达式来定义一个匿名的函数。例如

x => x%2==0

就定义了一个匿名的函数,这个函数的作用是判断一个参数是不是偶数。其中 “=>” 是C#中用用于定义lambda表达式的运算符,他前面的x是函数的输入参数,他后面是返回的结果,当x是偶数,即x除以2的余数等于0时返回true, 否则返回false。那么定义了这么一个lambda表达式有什么用呢?还是看一个例子。

比如说,有一个一维数组,保存着若干整数,现在需要计算出其中大于0的个数。那么按照传统方法可以这么写:

int c=0;
foreach(int i in numbers)
{
if(i>0) c++;
}

而如果在C#3.0中,使用 lambda表达式,代码就可以缩减到这样一个语句:

int c = numbers.Count(x => x>0 );

其中,Count() 是数组类型的一个方法,它的参数是一个lambda表达式,通过这个lambda表达式可以过滤参加统计的元素,就是说,只有大于零的元素才进行统计,这样,一句话就可以非常清晰地完成了上面的任务。

而这仅仅还是一个非常简单的要求,如果是这个例子的要求更复杂一些:“将一个整数数组中的所有正数选出来,各自求出其平方,然后按大小排序,构造出 一个新的数组”。那么这段程序可就需要做不少事情了,首先要对数组中的所有元素进行过滤,筛出大于0的数,然后每个数求出他的平方,然后对他们进行排序, 并且要构造一个新数组并填充结果。而在C#3.0中,通用可以使用一个语句完成上面的任务:

int[] n = numbers.Where(x => x>0 ).Select(x=>x*x).Orderby(x=>x).ToArray();

可以看到,上面的语句中,出现了3次 lambda表达式。Where、Select、Orderby这个三个方法调用,分别实现了过滤、平方、排序,他们都是以 lambda表达式作为参数传递到方法中,可见它的灵活和方便。

lambda表达式的数学来历

我 们看到了lambda表达式的作用,很容易我们会想到,为什么他们叫做“lambda”表达式这个“奇怪”的名字呢?实际上,这就倒回去80年了,在计算 机还处于“纸上谈兵”的年代,20世纪30年代,美国数学家阿隆佐.丘奇(Alonzo Church, 1903 – 1995)给出了一套用于研究函数定义和应用的形式系统,称为”λ演算“(lambda calculus)。

如果没有学习过相关内容,要完整地理解 lambda 演算,并不是很容易的一件事。这里给出一个最简单的例子,在 lambda 演算中,每个表达式都代表一个只有单独参数的函数,这个函数的参数本身也是一个只有单一参数的函数,同时,函数的值是又一个只有单一参数的函数。函数是通 过 lambda 表达式匿名地定义的,这个表达式说明了此函数将对其参数进行什么操作。

例如,一个函数 f(x) = x + 2 ,这是我们都很熟悉的书写方式,表示自变量(参数)为x,函数的值为“x+2”。如果用 lambda 演算表示,他的形式就变为了: λ x. x + 2。这里λ是一个固定的符号,后面的x表示参数,圆点后面表示函数的值是x+2,而 f(3) 的值写作 (λ x. x + 2) 3。更多的 lambda 表达式 相关的内容,这里不再介绍,可以参考wiki百科中相关的介绍。

那么如果仅仅是这么性形式上更换一个写法,当然也就没有什么实际意义了,而这么做的巨大意义在于,基于这样一套非常简明的规则,可以把“计算”这件事说清楚,即什么是可以计算的,以及如何使用通用的方式描述一个“计算”的过程?

就好象CSS为了描述页面布局,而设计出一套“盒子模型”,它是把页面布局中的最通用、最基本的一些特征提取出来,形成的若干规则。同样,”λ演算“是一套“计算的模型”,它是对计算的本质特征的描述。 lambda 演算与现代的计算机之间,还看不出直接的联系。而到了阿隆佐.丘奇的学生阿兰.图灵(Alan Turing)的时候,就把二者直接关联起来了。

 图灵机(英语:Turing Machine,又称确定型图灵机)是英国数学家阿兰·图灵于1936年提出的一种抽象计算模型,其更抽象的意义为一种数学逻辑机,可以看作等价于任何有限逻辑数学过程的终极强大逻辑机器。

也就是说,图灵“从理论上”设计出了现代的计算机,并给出了计算机的具体运行方式。而这个运行在“纸面上”的计算机,仅仅用几行文字就可以描述清 楚。在图灵发表了他的关于图灵机的理论十年之后,真正的计算机被真正制造出来。直到今天,我们使用的计算机,本质上看,不管你用的是“奔腾”还是“酷 睿”,仍然都是在在图灵机的模型上建立的,这就是数学的力量。人类的最重要的思维能力之一是“抽象”的能力,牛顿从苹果落地“抽象”出万有引力定律,图灵 从千变万化的计算中“抽象”出图灵机,包括CSS的设计者从页面布局中“抽象”出合资模型,本质都一样的,就是从纷繁复杂的表象之中,看到了隐藏在现象背 后的本质的规律。

由此,我们可以看到,数学的作用,正是从纷繁复杂的现象中寻找事物最本质的规律。

至于Lambda表达式,C#中引入并不算早的,在它之前,就已经有很多现代的编程语言中都实现了Lambda表达式。更为重要的是,我们当前进行开发,大多使用的C语言为代表这类过程性语言,实际上,还有一大类编程语言,与之区别甚大,称为“函数式语言”。

比如现在很热门的Erlang,以及很古老的Lisp,在国外大学教学中非常流行的SCHEME,甚至微软都已经推出了自己的函数语言F#。而全世界的第一个函数语言,就是这个并非为计算机设计的”λ演算“。 实际上,在计算机高级语言出现之初,函数语言和过程性的语言是同时开始的,但是几十年来的普及程度,过程性语言远远超过了函数式语言,具体原因大概是函数 语言并没有过程性语言方便。但是世道就是这样有趣,随着计算机硬件的发展,现在多核CPU的出现和普及,并行计算的要求越来越高,又使得函数式语言的优势 大大增加,从而使函数式语言大为热门。所以,研究历史、对比当前,发现到问题的本质,实在是很有趣的一件事。

如果对编程语言感兴趣,可以参考《编程语言的入门科普》和《编程语言分类学》。

再看C#中的lambda表达式

上面我们了解了C#新引入的“lambda表达式”这个特性,以及他的来历和数学基础,也简单演示了一下在C#中使用“lambda表达式”的作 用,但是如果仅仅是为了节省几个循环语句,是代码简洁一些,就太小看了“lambda表达式”的作用。实际上微软引入“lambda表达式”的意义远不止 于此,还有更大作用,这里就不再深入研究了。

写过一些程序的,比如用C语言或者C++、C#语言的读者有没有考虑过一个问题,尽管我们在程序中计算一个表达式的值很容易,比如这样一句话:

int x=3*(2+3);

就给x这个变量赋值为15了。

但是如果要您写一个程序,实现用户输入一个数学表达式的字符串,然后计算出结果,可就不那么容易了。写一个能够计算加减乘除、带有括号的四则运算的 程序,至少要在计算机系学到3年级的《编译原理》课程,才够用的。为什么呢?因为里面包含了很复杂的逻辑的,比如你需要能够把一个字符串,解析为运算的操 作数和运算符号,同时还要考虑,先乘除后加减的规则,以及括号的处理。若你可以没有学习任何相关基础的情况下,自己能够成功地写出这样一个程序,说明你绝 对是个非常非常聪明的人。

理论上说,计算机程序中包括两个部分:“数据”和“指令”,当我们把一个四则运算的表达式存储在字符串中的时候,它仅仅是一些数据,而不是指令,要真正计算出结果,需要把这个数据转换成指令,才能够进行计算。

因此,如果从更深层次看待这个问题的话,C#引入“lambda表达式”、以及“表达式树”这几个新特性以后,从基础层面,在“数据”和“指令”之 间搭建了一座桥梁,可以非常方便地相互转化。当一个表达式的逻辑通过“表达式数”以数据的形式保存以后,就可以方便地对他进行各种操作。具体内容这里不再 详细讨论。

当 然这方面还有很多工作可做。实际上,由Anders Hejlsberg主持的C#语言从1.0到即将发布的4.0,一直保持着相当快速的的前进步伐,C# 1.0实现了代码的托管,C# 2.0实现了泛型,C# 3.0引入了LINQ,C# 4.0将引入动态特性。一步一个脚印,而且每一个新特性都为后面的发展打下了坚实基础。

总而言之

在上面,我们结合C#语言中的一个特性,说明了一下它背后的数学背景。可以看出以下的一些结论,希望对读者有所帮助:

计算机科学的本质是数学

计算机成为一种科学,其实历史很短,不过几十年的时间。尽管现在的计算机已经成了日常消费品,而当初计算机科学的先驱们可都是大数学家。当然现在计 算机以及软件开发已经成为了一个巨大的产业,很多很多工作,都不需要数学家才能胜任了。否则,依靠着几个数学家,这么多事情可做不过来啊。

但是有一点我们要认清的是,越是重要的、底层的、基础性的工作,和数学的关系越密切。因此,我们作为普通人,可以看看自己的能力到哪层,就去寻找适合子的工作。

软件开发人员要学到什么程度才够用呢?

就像上面我提到的,现在整个产业已经变得巨大无比,因此层次也非常多,已经不存在一个明确的界限了,无论你有的基础如何,总是可以找到适当的位置 的。当然,如果你希望做一个程序员,数学还是一个需要重要因素的。做程序的人数学不好,就好象唱歌不认识乐谱,或者绘画不懂素描,对你的影响是很大的,

至于应该如何学习数学?我的感觉是: 1)先侧重于“广度”,2)然后再有重点地考虑“深度”,3)最重要的是提高学习能力。

第一句话的意思是:先侧重于“广度”的意思是,你先不管能理解多少,至少把那写必备的基础,都略知一二,即使不是真懂,至少也要知道一些重要的概念、大原则、大的思考方法。

第二句话的意思是:然后再考虑“深度”的意思是,在大致了解的基础上,在找一些相对直接有用的,深入地学习。

第三句话的意思是:任何人都不可能什么都掌握,很多东西都是在用到的时候,才会去具体研究学习,因此学习能力才是最重要的。


esp8266步进电机驱动控制 blinker控制步进电机起保停,正反转(Arduino uno+esp8266+TB6600驱动器) Arduino uno的板子的程序 esp8266板子接入到Arduino uno的控制引脚上的5,6,7 esp8266程序 //****库***** #define BLINKER_WIFI //官方wifi协议库 #define BLINKER_PRINT Serial //串口协议库 #include <Blinker.h&gt 阅读详情

相关推荐

C#-委托和lambda

C#-委托和lambda

weixin_44547407的博客 552

利用GBD数据库做未来疾病负担预测

最近看到一篇文献,利用GBD数据库中的数据对疾病负担的发展趋势进行预测。觉得很有趣,就抽空用R语言复盘了一下里面关键的方法。 参考文献: Changing trends in the disease burden of esophageal cancer in China from 1990 to 2017 and its predicted level in 25 years DOI: 10.1002/cam4.3775 1. 相关R包的安装 主要用到的R包有3个,一个一个讲: 1.1 Nordpred

NickyCat的博客 5万+

C#核心知识回顾——12.lambda表达式、List排序、协变和逆变

因为里氏替换原则 父类可以装子类 但是子类不能装父类。可以将lambad表达式理解为匿名函数的简写。内层的函数可以引用包含在它外层的函数的变量。所以比如object变成string。//用out修饰的泛型只能作为返回值。因为里氏替换原则 父类可以装子类。比如string变成object。//用in修饰的泛型只能作为参数。都是和委托或者事件配合使用的。即使外层函数的执行已经终止。逆常规的变化,不正常的变化。协变和逆变是用来修饰泛型的。C.通过委托函数实现排序。和谐的变化,自然的变化。//1.返回值和参数。

羽阿呆的博客 1583

PyQt 随笔:信号与槽的两种使用方法:@pyqtSlot 和 connect

在 PyQt 中,信号与槽是实现事件驱动的一种重要机制。通过信号与槽的连接,可以实现对象之间的通信,例如在用户界面中响应按钮点击事件或者数据的变化等。PyQt 提供了两种主要的方法来创建信号与槽的连接:@pyqtSlot 装饰器和 connect 方法。本文将详细介绍这两种方法,并提供相应的源代码示例。在上面的示例中,我们定义了一个名为。

QasdCpp的博客 763

从零到一,打造你的无人机侦察兵!树莓派+Python+MQTT,实时目标检测全攻略

物联网、人工智能与计算机视觉三大前沿技术的深度融合。

u013558123的博客 1473

C# 8 的模式匹配

C# 7里面的Pattern Mathing叮当小说网 https://www.guxs.net/ 更多内容请查看官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-8#more-patterns-in-more-places?WT.mc_id=DT-MVP-5003302 is 模式 ...

代码小牛的博客 654

基于Python的农业市场价格抓取与供需分析:现代爬虫技术与实战应用

在正式开始爬虫开发之前,我们首先了解爬虫的基本概念和工作原理。爬虫(Web Scraping)是通过编程的方式,自动从互联网上获取信息的技术。它可以帮助我们提取HTML页面中的特定数据,通常用于收集并处理大量信息。发送HTTP请求:爬虫需要向目标网站发送请求,获取网站的HTML页面内容。解析HTML页面:通过HTML解析器对获取的页面内容进行解析,提取其中需要的数据。数据清洗与存储:将提取的数据进行清洗,去除多余的字符或无关内容,然后存储到合适的格式(如CSV文件、数据库等)中。数据分析与可视化。

2201_76125261的博客 1117

C#Lambda让代码变得更加简洁而优雅

  在使用lambda表达式时,可以使代码更加简洁和优雅。

dawn0718的专栏 1503

把 ABAP Unit 测试放进本地类:让重构更安全、让测试更好找的组织方式

ABAP测试代码组织策略:单元测试与集成测试的合理存放位置 本文针对ABAP开发中测试代码组织混乱的问题,提出了一套系统化的解决方案: 单元测试应存放在被测类的本地测试include中(...CCAU或...T99),确保测试与代码同步演进且易于发现 跨对象测试(组件/集成/系统测试)应创建单独的全局测试类,并通过FOR TESTING和ABSTRACT进行防护 使用! @testing注释建立测试关系,使测试与被测对象明确关联,提高可发现性 针对不同技术栈(RAP/CAP/OData)提供了具体落地建议,

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1729

华为OD机试真题 新系统2026-04-01 C++ 实现【计算数列位置N的值】

如果其前面的M个元素中,存在值相同的元素,则该位置上的数值等于前面M个数中最大的数值与最小的数值之如果其前面的M个元素中,不存在值相同的元素,则该位置上的数值等于前面M个数中最大的数值与最小的数值之差;1、输入M、N两个数,则按照以下规则形成一个数列;两个整数,用逗号分割,分别表示M和N。一个整数,表示数列第N个位置上的数值。2、数列的前M个元素的值为1到M;请计算该数列第N个位置上的数值。N取值范围:1<= N<=50。M取值范围:3<=M<=10。

MISAYAONE的博客 1153

C#语言中从Switch语句转换到Switch表达式

*Switch 语句:**传统上,C# 中的 switch 语句具有冗长的语法,要求对每个情况使用 and 关键字,并对处理不匹配的值使用一个情况。**Switch 语句:**在 switch 语句中,每个大小写都必须显式匹配 switch 变量的类型。**Switch 语句:**switch 语句中的错误可能仅在运行时被捕获,从而导致潜在的错误。**切换表达式:**开关表达式可以从大小写推断开关变量的类型,从而减少类型声明中的冗余。**Switch 语句:**不能直接在 lambda 表达式中使用。

2401_82584055的博客 883

Android开发工程师(IOT)面试指南与参考答案

【摘要】绿联科技招聘Android开发工程师(IOT方向),要求5年以上Android开发经验,精通Kotlin/Java,熟悉IOT设备交互及跨平台开发。岗位职责包括客户端开发维护、技术调研及性能优化等。核心考察点包括:Kotlin协程在IOT低功耗场景的应用、多协议设备连接层设计、音视频性能优化及离线架构实现。重点技术涉及蓝牙Mesh群控、BLE功耗优化及ReactNative混合开发。需具备GooglePlay合规经验,熟悉Android13+权限管理,并能提供量化性能优化案例。

郑伟强dev的专栏 723

【C# 委托 Lambda表达式】一个简单的例子

委托 委托类似于C++函数指针,但委托是完全是面向对象的,是安全的数据类型。 委托允许将方法作为参数进行传递。 运行结果 j=25 代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 第八...

寒泉 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

由简单例子了解C#中的委托和Lambda表达式

最近一直在实习,觉得自己的基础还是不行,遇到复杂的代码还是很不容易理解,于是又重温了《C#本质论》,便写下了这篇笔记。 委托(delegate):允许像处理其他任何数据一样处理对方法的引用。 Lambda表达式:可以快速和简单地创建自定义委托。 委托 C/C++中允许程序员利用”函数指针“将对方法的引用作为实参传递给另一个方法。C#则使用委托提供了相同的功能。委托允许捕捉对方法的引用,并像...

Lenny的博客 444

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

小例子学习C#委托和Lambda表达式

首先提出一个问题:给你很多的姓名,让你找出一个姓氏的所有人,用程序实现。 这个程序用很多方法可以实现,这篇博文中,我们就利用委托和Lambda表达式的方法实现。 首先把所有的姓名放到一个集合中 List<string> list = new List<string> { "田三涛", "刘起涵", "张晓轩", "田圣彤", "文筠彤", "刘起涵", "田优乔",...

weixin_34250434的博客 69

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C#的Lambda表达式嵌套例子

1 /* 2 *curStatsResult是List&lt;string&gt;类型, 3 *x.GetAllOsVersion()结果是string[]类型, 4 *这里是先使用SelectMany()返回一个结果,再用Count()进行统计数字 5 *而不是在SelectMany()中直接使用Count()方法 6 */ 7 int amd64CountPart ...

weixin_34199405的博客 447

C# Lambda表达式使用累加器例子

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LambdaSample { class Program { static void Main(string[] args) { ...

weixin_30666943的博客 241

C#委托+lambda表达式+泛型 结合语法糖简单例子详解

最近学习了lambda表达式,遇到一些比较难看懂的语法。这里用很简单的例子帮大家理解lambda有关的语法糖。先来看一下普通的内联lambda表达式 //lambda/inline            Func&lt;int, int, int&gt; func = new Func&lt;int, int, int&gt;((int a, int b) =&gt; { return a + b...

ikunsaikou的博客 1403

一个例子帮你搞懂C#语言高级特性系列(02) --- 委托、事件和Lambda表达式

所谓的委托(delegate)在C语言中叫指向函数的指针,C++中叫仿函数(functor,有些翻译为函数对象),在Java中通过单方法接口回调(callback)来实现。说白了,就是把一个函数通过参数传到另一个函数里面。

骆昊的技术专栏 2025

C#-Lambda 表达式

C# 中的lambda 表达式以上就是今天的内容了,简单介绍下Lambda表达式。

Bruce__taotao的博客 1342

C#教程:作为委托的Lambda表达式

作为委托的Lambda表达式 从很多方面看, Lambda表达式可以被看成是C# 2中匿名方法的进化. 几乎没有什么匿名方法能做而Lambda表达式不能做的事情, 而Lambda表达式几乎总是能提供更好的可读性且更简洁. 特别的, lambda表达式和匿名方法捕获变量的行为是完全一致的. 在两者多数的显式行为当中并没有存在太多的不同——不过lambda表达式拥有大量的快捷方式, 这在很多常规情况下使得代码更加简洁. 与匿名方法一样, lambda表达式也拥有自己特殊的转换规则——表达式本身的类似并不是

上善若水 的专栏 1128

C#Lambda表达式总结

C#Lambda表达式总结

过客 1820

c++ Lambda 表达式

c++ Lambda 表达式

xie__jin__cheng的博客 1194
上一篇: 用Adobe Flex3开发AIR应用程序–入门指南
下一篇: MFC通过ADO操作Access数据库
CB_CB
博客等级 码龄18年 13粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值