C# 对象作为参数_C#委托事件机制:感性认识委托(1)

感谢刘铁猛老师的《C#入门详解》和擅码网Monkey老师的《C#面向对象基础》

本专栏的委托与事件部分已经更新完毕,跳转链接如下:

第一篇:感性认识委托

感性认识委托 - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/146341073

第二篇:函数指针:委托的由来

函数指针:委托的由来 - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/146637091

第三篇:委托的用法

委托的用法 - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/147242231

第四篇:感性认识事件

闹钟响了我起床——感性认识事件 - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/147932169

第五篇:事件的调用

事件的调用 - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/148561855

第六篇:事件的完整声明,触发和事件的本质

事件的完整声明,触发和事件的本质 - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/150967817

第七篇:为什么我们需要事件&补充和总结

为什么我们需要事件&补充和总结 - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/162065756

第八篇:用委托事件机制模拟游戏场景

浅谈C#委托事件机制:开阔地机枪兵对射问题(8) - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/166465013

每个程序员都会对自己掌握的第一门语言怀有特殊感情,对我来说,这种语言正是C#;希望我的文字能为大家带来一点帮助,还请多多指教~

作为系列的第一篇文章;我们首先来讨论“委托”[delegate]这个东西是什么,有什么作用


委托是C#的五种基本数据类型之一(C#包括两种值类型:枚举,结构体及三种引用类型:类,委托和接口);委托[delegate]事件[event]共同构成了C#中最复杂的语法机制。

本篇文章试图说明委托是个什么东西,让大家有个感性的认知,进而再说明委托的常规用法,并未后面的事件[event]机制埋一个引子。

什么是委托:

从字面意思上说,“委托”就是一件事,我们不亲自去做,而是把这件事交给其他人帮忙做;我们知道,编程语言是人类自然语言的一个小小子集,仅用于实现自然语言中涉及逻辑的部分;而“委托”这种语法机制也是一种C#语言对现实世界逻辑的抽象。

怎样理解“把这件事交给其他人帮忙做”呢?

我们知道,程序由数据+算法组成,在面向对象语言中,类和对象是对现实事物的抽象,类的三种主要成员分别是:负责保存数据的字段,描述了类或对象的状态(以及用于保护字段的属性);用于实现逻辑的方法,决定了类或对象可以做什么(也就是函数,尽管Function这个词似乎翻译成"功能"更妥当一些);以及用于通知其它类或对象来进行协调与信息交换的事件(后面我们会知道,事件是一种对委托的封装)

在这三种主要成员的作用下,面向对象编程得以在虚拟世界中对现实世界发生的种种逻辑进行模拟;通常来说,方法本身已经足以胜任“实现逻辑”了;为什么还需要委托呢?

第一个原因是:在一个复杂的算法中,方法之间存在大量互相调用的需求;

此时我们可以把符合某种特征的方法给抽象出来,人为规定:凡是符合这种特征的方法都可以被委托托管

这里的“托管”有三层意思,一是委托可以用于调用方法二是委托可以将方法封装以作为其它方法的参数三是委托可以作为一种约束,限制方法的调用

现在我们先来说第一层意思:

委托是对方法的托管,可以用于调用方法

例如我们可以定义一个宅男类;宅男的初始情况是饿的,于是他需要去吃饭;

“吃饭”这件事包括五个具体的步骤:

1>.走进餐厅

2>.找个位子坐下来

3>.想一想,该吃些什么呢?

4>.点菜

5>.吃

代码如下:

//定义一个宅男类

现在,我们的Rosen同学就是这个宅男,我们要让他不被饿死,当然可以这样:

static 

输出为:

我走进了餐厅...

我坐了下来...

该吃点什么呢?

该吃点什么呢?

该吃点什么呢?

该吃点什么呢?

该吃点什么呢?

就决定要吃你了!小笼包子!!

我吃了小笼包子!,我饱了

但我们很容易意识到:吃饭这件事其实没必要那么复杂,这五个具体的步骤其实都是为了服务吃饭那个目标,而且,这五个步骤其实是性质相同的事情:在现实世界中,这种性质相同或许体现为他们都是宅男调用自己的“硬件”去完成的工作,而在程序世界中,这种“性质相同”则体现为:这五个方法的返回值都是空,且参数列表都为空

于是,我们可以把这五种方法抽象为同一类东西,这个东西就是委托。

委托的标准声明格式为:

delegate method-return-type delegate-name (params-list);

其中,委托的返回值类型必须与method-return-type一致,而参数列表也必须与params-list一致

现在我们开始为“给宅男找吃的所需要的步骤”声明委托:

//定义一种委托类型,这种委托可以封装参数列表为空,没有返回值的方法

(注意,委托作为类成员应该定义在类下,不能定义在方法体里)

然后,我们可以实例化一个FindSthToEat委托来封装完成吃饭这个目标所需要的五个方法:

static 

(注意,因为这里封装的是非静态方法,所以必须要先创建一个类的实例来引出这些方法)

现在,我们不用再像原来那样一个方法一个方法的调用了,我们直接调用这个委托就能实现一样的效果:

static 

输出当然还是原来的:

我走进了餐厅...

我坐了下来...

该吃点什么呢?

该吃点什么呢?

该吃点什么呢?

该吃点什么呢?

该吃点什么呢?

就决定要吃你了!小笼包子!!

我吃了小笼包子!,我饱了

看到这里,大家大概已经发现了,委托和方法非常像,甚至可以和方法一样用方法调用操作符“f(x)”来调用。

事实上,委托的实例就是一种特殊的方法;当委托作为数据类型存在的时候,可以将符合某种特征的方法抽象为一种数据类型,而当委托被实例化之后,委托的实例就是一个封装着其它方法的“大号方法”。

至于为什么我们需要这个“大号”方法,除了更灵活,可以随时增删内容以外,还有另外三个原因。

1>.委托可以将方法封装为其它方法的参数

2>.来自C语言和C++语言的语法传承(将在本系列的第二篇文章讲解,涉及函数指针)

3>.委托可以作为一种约束条件来限制方法的调用(将在本系列的第四篇文章讲解,涉及事件的本质)

我们先来讨论第一点。

委托可以将方法封装为其它方法的参数

举个例子:

宅男每天上午要上班,然后吃午饭,再度过午休时光。吃饭是一定要吃的,虽然他已经很胖了,但他总怕饿死自己;而吃完饭后他可以根据当天的心情在三件事中选一件来做:

1>.刷B乎

2>.睡觉

3>.玩游戏

我们来定义这三个方法(顺便也定义一下上班的方法):

public 

在度过午休之后,他又要去上班了。

在这个模型中,我们发现,上学和吃饭都是必须进行的固定操作,而午休时做什么是可选且只能选一个的,而且宅男每天中午做的事情并不一致。

我们如果写一个方法来概括他一天的行程,午休这里就难以处理:如果写入了刷B乎,睡觉或玩游戏中的任何一个,那宅男就永远无法在其它的日子的午休时间里做其它事了。

这时,我们就可以引入委托的另一个功能:委托可以作为形式参数被其它方法调用,如果可以先执行那些写死的逻辑,在需要灵活变化的位置执行作为参数被传入的委托,这个问题不就解决了?

比如,我们来写一个方法,概括宅男一天的行程;

为此,我们先定义一个委托以待作为参数使用:

//定义一种委托类型,这种委托可以封装参数列表为空,没有返回值的方法

然后我们来写这个方法:

public 

这种写法成立的原因:形式参数由参数的数据类型和形式参数名组成,而委托本身就是一种人为定义的数据类型——只不过这种数据类型描述的是方法罢了

现在,我们每天都能为宅男安排不同的午休内容了:

static 

输出为:

现在是周一

996是我修来的福报!

我吃了午饭,我饱了

我刷了B面的知乎,里面各个都是人才,我超喜欢里面的!

996是我修来的福报!

真是美好的一天啊...

现在是周二

996是我修来的福报!

我吃了午饭,我饱了

我睡着啦...

996是我修来的福报!

真是美好的一天啊...

现在是周三

996是我修来的福报!

我吃了午饭,我饱了

嘤嘤嘤,没有野王带带瑶瑶吗?瑶瑶超可爱的QAQ

996是我修来的福报!

真是美好的一天啊...

事实上,很多程序员称“委托”为“方法的数据类型参数化”,可见,委托的这种作用是非常 泛用的。

至此,我们已经对委托有了一个初步的认识;至于委托的其它用法,以及这种奇怪声明方式的由来,我们下期再见!

———————————————————————————

对于非科班选手的计算机学习之路,可以看我的另一篇回答:

https://www.zhihu.com/answer/1185042118

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值