本来是想写一篇《委托与lambda表达式的前世今生》,但仅委托部分已经写了很多内容,于是就此分开关于Lambda表达是的内容后续再写吧。

不知道Lambda表达式是谁发明的,只记得第一次接触Lambda表达式是在使用VS2008的时候,那就先认为是微软发明的吧。
Lambda表达式从我接触开始到现在变得越来越流行,Java8中开始支持、kotlin更是对C#,F#做了广泛的抄袭(C#曾几何时不也如此对待过Java嘛)。其实这都充分说明了,Lambda表达式的重要性。要搞清楚Lambda首先需要搞清楚委托。
委托:
假设现在我们要开发一个处理两个整数的程序(假设先处理相加操作)
public class Worker
{
/// <summary>
/// 处理两个数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public int HandleTwoNumber(int a,int b)
{
return a + b;
}
}
static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
Worker worker = new Worker();
int result = worker.HandleTwoNumber(a, b);
Console.WriteLine(String.Format("Result:{0}", result));
string p = Console.ReadLine();
}
如果一段时间后,我们需要它变更为减操作:
public class Worker
{
public int HandleTwoNumber(int a,int b)
{
return a - b;
}
}
虽然有a+b变为a-b的变化很微小,但后续此处可能面临多次变化(由减变为除.........)。有变化就应封装变化,此处我们可以将a与b的操作行为抽象出来,用什么抽象呢?委托
public class Worker
{
public delegate int TwoNumberHandleMethodDelegate(int x, int y);
public int HandleTwoNumber(int a,int b)
{
return a + b;
}
}
public delegate int TwoNumberHandleMethodDelegate(int x, int y);此处用delegate标注,表明这是一个委托定义。如果去掉 delegate 再来观察该定义,你会发现这就是一个没有方法体的抽象方法。所以委托的含义即:与该抽象方法签名形式相同的方法的类型。委托就是一种你定义的新数据类型,它与int、class是一样的都是数据类型。int表示整数,只要是整数都可以赋值给 int型变量;TwoNumberHandleMethodDelegate则表示,接收两个int型参数并返回int型结果的这类方法,因此满足上述要求的方法都可赋值给TwoNumberHandleMethodDelegate类型的变量。
如此一来Worker代码可修改为:
public class Worker
{
public delegate int TwoNumberHandleMethodDelegate(int x, int y);
public int HandleTwoNumber(int a, int b, TwoNumberHandleMethodDelegate handle)
{
return handle(a, b);
}
}
如此a、b的操作被封装起来,所有的变化均交由调用者来处理。此处的含义:HandleTwoNumber处理a、b两个整数,具体如何处理由 handle 实施。此时你可能会问,那如何来调用该方法呢?调用如下:
private static int Add(int a, int b)
{
return a + b;
}
private static int Sub(int a, int b)
{
return a - b;
}
static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add);
Worker worker = new Worker();
int result = worker.HandleTwoNumber(10, 10,method);
//int result = worker.HandleTwoNumber(10, 10, Sub);//简化版
Console.WriteLine(String.Format("Result:{0}", result));
}
根据上面的程序可知,Main代码块为worker的调用者,作为调用者而言应该最清楚自己想要让woker做的工作。因此作为被调用者的worker而言,它只需要接收调用者Main给的a\b参数及执行Main定制的算法method,然后按照算法执行并返回结果即可。上面代码虽然简单,但其中的意义深远,随着编程时间的增加相信你的理解将越深刻。
委托变量在进行赋值时除了标准的方式,还可以进行简化:
Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add);
Worker worker = new Worker();
int result = worker.HandleTwoNumber(10, 10,method);
//可简化为
// int result = worker.HandleTwoNumber(10, 10,Add);
编译器将自动检查Add是否符合 TwoNumberHandleMethodDelegate 的定义,如果符合允许直接将方法名赋值给委托变量。
匿名委托
通过上面的示例代码,我们很容易发现 TwoNumberHandleMethodDelegate method 变量被赋值为Add(Sub),因此在调用method(...)时相当于调用Add(.....)。这样一来就可以认为
method与Add完全等效,既然等效那是否可以直接将Add的定义内容赋值给method变量呢?答案是肯定的:
static void Main(string[] args)
{
Worker.TwoNumberHandleMethodDelegate method =private static int Add(int a, int b)
{
return a + b;
};
}
但像上面这种生拉硬套是不行的,你还需要做修改。修改内容是:因为现在的代码处于Main方法中,访问修饰符去掉,同样static也应去掉;同时编译器知道你要给method赋值,那么要赋的这个值肯定满足返回类型为int的要求,所有int在此时就多余了去掉;因为赋值之后method就等效于Add,以后调用只要通过method变量就可完成,所有Add方法名不需要去掉。如此代码变为如下形式:
static void Main(string[] args)
{
Worker.TwoNumberHandleMethodDelegate method = (int a, int b)
{
return a + b;
};
}
经过上面的修改内容简化了很多,但method赋值的=右端是什么东西呢?此时编译器并不能正确识别这是一个方法,因为方法的定义需要满足包含:访问修身符、返回类型、方法名、参数列表、方法体五部分内容。虽然你心里清楚这是个简化了的方法,但是编译器不懂你的心.........,那没关系只要我们告诉编译器,后面的是个简化方法就可以了。
static void Main(string[] args)
{
Worker.TwoNumberHandleMethodDelegate method = delegate(int a, int b)
{
return a + b;
};
}
正如你所期望的那样,现在编译器已经知道了=右侧是你经过简化的方法;ok,现在可以正常赋值并使用了。
通过上面的定义我们发现,用delegate标注的简化方法没有一个像Add/Sub一样固定的名字。因此我们称这种方法叫匿名委托(我习惯称匿名方法)。
你可能还注意到该匿名委托定义完毕后就赋值给Main代码快中的局部变量method,因此当超出method的作用域后,该方法就再也没有机会调用了。这引出了匿名方法、匿名委托、匿名函数它们的最常见用法,即用来定义只需要使用一次的功能代码。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# C#
# 委托
# 匿名委托
# 详解c# 委托链
# c# 委托的本质是什么
# C# 引入委托的目的是什么
# 一篇文章彻底搞清楚c#中的委托与事件
# C#用委托BeginInvoke做异步线程
# C#使用委托的形式调用线程代码实例
# C#沉淀之委托的深入讲解
# C# WPF 通过委托实现多窗口间的传值的方法
# C#匿名委托与Lambda表达式详解
# c# 委托详解
# c# 委托的常见用法
# 调用者
# 这是一个
# 就可以
# 都是
# 是一个
# 是个
# 是在
# 还可以
# 也没
# 在此
# 不需要
# 不懂
# 有机会
# 很容易
# 我们可以
# 这就
# 微软
# 用了
# 这类
# 要做
相关文章:
GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?
较简单的网站制作软件有哪些,手机版网页制作用什么软件?
Swift中swift中的switch 语句
网站制作公司排行榜,抖音怎样做个人官方网站
视频网站制作教程,怎么样制作优酷网的小视频?
建站之星logo尺寸如何设置最合适?
大型企业网站制作流程,做网站需要注册公司吗?
南阳网站制作公司推荐,小学电子版试卷去哪里找资源好?
如何快速搭建FTP站点实现文件共享?
如何在云主机上快速搭建网站?
建站之星安全性能如何?防护体系能否抵御黑客入侵?
建站之星如何防范黑客攻击与数据泄露?
b2c电商网站制作流程,b2c水平综合的电商平台?
如何解决ASP生成WAP建站中文乱码问题?
网站制作报价单模板图片,小松挖机官方网站报价?
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
如何优化Golang Web性能_Golang HTTP服务器性能提升方法
实现点击下箭头变上箭头来回切换的两种方法【推荐】
整蛊网站制作软件,手机不停的收到各种网站的验证码短信,是手机病毒还是人为恶搞?有这种手机病毒吗?
简单实现Android文件上传
网站制作免费,什么网站能看正片电影?
临沂网站制作企业,临沂第三中学官方网站?
深入理解Android中的xmlns:tools属性
微课制作网站有哪些,微课网怎么进?
C#怎么创建控制台应用 C# Console App项目创建方法
教程网站设计制作软件,怎么创建自己的一个网站?
交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?
网站制作大概多少钱一个,做一个平台网站大概多少钱?
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
模具网站制作流程,如何找模具客户?
Swift中循环语句中的转移语句 break 和 continue
SQL查询语句优化的实用方法总结
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
建站主机解析:虚拟主机配置与服务器选择指南
如何选择域名并搭建高效网站?
建站三合一如何选?哪家性价比更高?
文字头像制作网站推荐软件,醒图能自动配文字吗?
一键制作网站软件下载安装,一键自动采集网页文档制作步骤?
ppt制作免费网站有哪些,ppt模板免费下载网站?
北京网站制作的公司有哪些,北京白云观官方网站?
如何通过VPS搭建网站快速盈利?
广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的?
,在苏州找工作,上哪个网站比较好?
nginx修改上传文件大小限制的方法
专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?
如何在IIS中新建站点并配置端口与物理路径?
专业网站建设制作报价,网页设计制作要考什么证?
*请认真填写需求信息,我们会在24小时内与您取得联系。