托付

我们先无论这个标题怎样的绕口。也无论托付到底是个什么东西,来看以下这两个最简单的方法,它们只是是在屏幕上输出一句问候的话语:

如果这个程序须要进行全球化。哎呀,不好了,我是中国人,我不明确”Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法:

这时候。GreetPeople也须要改一改了,不然怎样推断究竟用哪个版本号的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为推断的根据:

OK。虽然这样攻克了问题。但我不说大家也非常easy想到,这个解决方式的可扩展性非常差,假设日后我们须要再加入韩文版、日文版,就不得不重复改动枚举和GreetPeople()方法,以适应新的需求。

在考虑新的解决方式之前,我们先看看 GreetPeople的方法签名:

public void GreetPeople(string name, Language lang)

MakeGreeting(name);

好了,有了思路了,我们就来改改GreetPeople()方法。那么它应该是这个样子了:

注意到 。这个位置通常放置的应该是參数的类型,但到眼下为止。我们不过想到应该有个能够代表方法的參数,并按这个思路去改写GreetPeople方法,就出现了一个大问题: *这个代表着方法的MakeGreeting參数应该是什么类型的?

NOTE:这里已不再须要枚举了,由于在给MakeGreeting赋值的时候动态地决定使用哪个方法,是ChineseGreeting还是 EnglishGreeting,而在这个两个方法内部。已经对使用”morning”还是”早上好”作了区分。

聪明的你应该已经想到了,是托付该出场的时候了。但讲述托付之前,我们再看看MakeGreeting參数所能代表的 ChineseGreeting()和EnglishGreeting()方法的签名:

于是,托付出现了: 它定义了MakeGreeting參数所能代表的方法的种类,也就是MakeGreeting參数的类型。

NOTE:假设上面这句话比較绕口。我把它翻译成这样:string 定义了name參数所能代表的 值的种类,也就是name參数的类型。

本例中托付的定义:

public delegate void GreetingDelegate(string name);

能够与上面EnglishGreeting()方法的签名对照一下,除了增加了delegatekeyword以外,其余的是不是全然一样?

让我们再次修改GreetPeople()方法,例如以下所看到的:

输出例如以下:

Morning, Jimmy Zhang

早上好, 张子阳

我们对托付做一个总结:

看到这里。是不是有那么点如梦初醒的感觉?于是,你是不是在想:在上面的样例中,我不一定要直接在GreetPeople()方法中给 name參数赋值,我能够像这样使用变量:

而既然托付GreetingDelegate 和 类型 string 的地位一样,都是定义了一种參数类型,那么,我是不是也能够这么使用托付?

输出为:

Morning, Jimmy Zhang

早上好, Jimmy Zhang

实际上。我们也能够绕过GreetPeople方法。通过托付来直接调用EnglishGreeting和ChineseGreeting:

NOTE:这在本例中是没有问题的,但回头看下上面GreetPeople()的定义,在它之中能够做一些对于EnglishGreeting和ChineseGreeting来说都须要进行的工作,为了简便我做了省略。

我们也能够使用以下的代码来这样简化这一过程:

GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);

delegate1 += ChineseGreeting; // 给此托付变量再绑定一个方法

看到这里,应该注意到,这段代码第一条语句与实例化一个类是何其的相似。你不禁想到:上面第一次绑定托付时不能够使用”+=”的编译错误,也许能够用这个方案来避免:

GreetingDelegate delegate1 = new GreetingDelegate();

delegate1 += EnglishGreeting; // 这次用的是 “+=”,绑定语法。

delegate1 += ChineseGreeting; // 给此托付变量再绑定一个方法

既然给托付能够绑定一个方法,那么也应该有办法取消对方法的绑定,非常easy想到。这个语法是”-=”:

输出为:

Morning, Jimmy Zhang

早上好, Jimmy Zhang

早上好, 张子阳

让我们再次对托付作个总结:

我们继续思考上面的程序:上面的三个方法都定义在Program类中,这样做是为了理解的方便,实际应用中。通常都是 GreetPeople 在一个类中,ChineseGreeting和 EnglishGreeting 在另外的类中。你已经对托付有了初步了解,是时候对上面的样例做个改进了。如果我们将GreetingPeople()放在一个叫GreetingManager的类中,那么新程序应该是这个样子的:

这个时候,假设要实现前面演示的输出效果,Main方法我想应该是这种:

Morning, Jimmy Zhang

早上好, 张子阳

如果我们须要使用上一节学到的知识,将多个方法绑定到同一个托付变量,该怎样做呢?让我们再次改写代码:

输出:

Morning, Jimmy Zhang

早上好, Jimmy Zhang

我们能够这样使用这个托付变量:

输出为:

Morning, Jimmy Zhang

早上好, Jimmy Zhang

虽然这样做没有不论什么问题,但我们发现这条语句非常奇怪。在调用gm.GreetPeople方法的时候,再次传递了gm的delegate1字段:

gm.GreetPeople(“Jimmy Zhang”, gm.delegate1);

既然如此,我们何不改动 GreetingManager 类成这样:

在client,调用看上去更简洁一些:

输出为:

Morning, Jimmy Zhang

早上好, Jimmy Zhang

虽然这样达到了我们要的效果,可是还是存在着问题:

在这里,delegate1和我们平时用的string类型的变量没有什么分别,而我们知道,并非全部的字段都应该声明成public,合适的做法是应该public的时候public,应该private的时候private。

我们先看看假设把 delegate1 声明为 private会如何?结果就是: 这简直就是在搞笑。由于声明托付的目的就是为了把它暴露在类的client进行方法的注冊。你把它声明为private了,client对它根本就不可见。那它还有什么用?

再看看把delegate1 声明为 public 会如何?结果就是: client能够对它进行任意的赋值等操作,严重破坏对象的封装性。

最后。第一个方法注冊用”=”。是赋值语法。由于要进行实例化,第二个方法注冊则用的是”+=”。可是。不 管是赋值还是注冊,都是将方法绑定到托付上。除了调用时先后顺序不同,再没有不论什么的分别。这样不是让人认为非常别扭么?

我们想想。假设delegate1不是一个托付类型。而是一个string类型,你会怎么做? 答案是使用属性对字段进行封装。

我们改写GreetingManager类,它变成了这个样子:

为了证明上面的推论。假设我们像以下这样改写Main方法:

会得到编译错误:事件”Delegate.GreetingManager.MakeGreet”仅仅能出如今 += 或 -= 的左边(从类型”Delegate.GreetingManager”中使用时除外)。

这时候,我们凝视掉编译错误的行。然后又一次进行编译,再借助Reflector来对 event的声明语句做一探究,看看为什么会发生这种错误:

public event GreetingDelegate MakeGreet;

能够看到。实际上虽然我们在GreetingManager里将 MakeGreet 声明为public,可是,实际上MakeGreet会被编译成 私有字段。难怪会发生上面的编译错误了。由于它根本就不同意在GreetingManager类的外面以赋值的方式訪问,从而验证了我们上面所做的推论。

我们再进一步看下MakeGreet所产生的代码:

关于这个类的更深入内容,能够參阅《CLR Via C#》等相关书籍,这里就不再讨论了。

输出为:

Alarm:嘀嘀嘀,水已经 96 度了:

Alarm:嘀嘀嘀,水已经 96 度了:

Display:水快烧开了,当前温度:96度。

// 省略…

我们须要写个程序来模拟这个烧水的过程,我们将定义一个类来代表热水器,我们管它叫:Heater,它有代表水温的字段。叫做temperature。当然。还有不可缺少的给水加热方法BoilWater(),一个发出语音警报的方法MakeAlert(),一个显示水温的方法。ShowMsg()。

上面的样例显然能完毕我们之前描写叙述的工作,可是却并不够好。如果热水器由三部分组成:热水器、警报器、显示器。它们来自于不同厂商并进行了组装。那么。应该是 热水器只负责烧水。它不能发出警报也不能显示水温;在水烧开时由 警报器发出警报、 显示器显示提示和水温。

这时候。上面的样例就应该变成这个样子:

这里就出现了一个问题:怎样在水烧开的时候通知报警器和显示器?在继续进行之前,我们先了解一下Observer设计模式,Observer设计模式中主要包含例如以下两类对象:

在回答上面的问题之前,我们先搞懂 .Net Framework的编码规范:

输出为:

Alarm:China Xian – RealFire 001:

Alarm: 嘀嘀嘀,水已经 96 度了:

Alarm:China Xian – RealFire 001:

Alarm: 嘀嘀嘀。水已经 96 度了:

Alarm:China Xian – RealFire 001:

Alarm: 嘀嘀嘀。水已经 96 度了:

Display:China Xian – RealFire 001:

// 省略 …

在本文中我首先通过一个GreetingPeople的小程序向大家介绍了托付的概念、托付用来做什么,随后又引出了事件,接着对托付与事件所产生的中间代码做了粗略的讲述。

希望这篇文章能给你带来帮助。

Original: https://www.cnblogs.com/cynchanpin/p/7403780.html
Author: cynchanpin
Title: 托付

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/551484/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Html5+Css3BannerAnimation多方位移动特效

    背景:朋友问我小米官网的mi4的特效会做吗,可能新接的一个小网站需要用到。一直有打算研究H5C3的一些效果,趁此机会,赶紧学习一下! 效果:如图 素材 HTML: STYLE: J…

    技术杂谈 2023年7月24日
    073
  • 2021.07.13 我们是这样崩的

    至暗时刻 2021年7月13日22:52,SRE收到大量服务和域名的接入层不可用报警,客服侧开始收到大量用户反馈B站无法使用,同时内部同学也反馈B站无法打开,甚至APP首页也无法打…

    技术杂谈 2023年5月30日
    090
  • 003Linux查看文件内容的5个命令姿势

    Linux 中查看文件内容常用的有如下 5 个命令: cat cat 命令常用格式示例: cat [文件名] # 输出文件所有内容到屏幕上。 cat [文件1] [文件2] # 输…

    技术杂谈 2023年7月10日
    082
  • GPS卫星同步时钟,NTP网络同步时钟,北斗时钟服务器(京准)

    GPS卫星同步时钟,NTP网络同步时钟,北斗时钟服务器(京准) GPS卫星同步时钟,NTP网络同步时钟,北斗时钟服务器(京准) 安徽京准电子科技官微——ahjzsz 一、时钟系统基…

    技术杂谈 2023年6月21日
    073
  • Dijkstra算法求最短路

    例题链接 Dijkstra算法是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。其主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的…

    技术杂谈 2023年6月21日
    093
  • Netty源码分析之ByteBuf(一)—ByteBuf中API及类型概述

    ByteBuf是Netty中主要的数据容器与操作工具,也是Netty内存管理优化的具体实现,本章我们先从整体上对ByteBuf进行一个概述; AbstractByteBuf是整个B…

    技术杂谈 2023年7月25日
    061
  • kettle插入更新

    kettle实现若主键存在则更新,若主键不存在则插入 Original: https://www.cnblogs.com/cheng9999/p/14085922.htmlAuth…

    技术杂谈 2023年7月24日
    082
  • 【转】重新理解微服务之它还那么纯粹吗?

    原文:https://www.cnblogs.com/skychen1218/p/16406274.html Original: https://www.cnblogs.com/o…

    技术杂谈 2023年5月30日
    083
  • dremio 的一些系统表

    dremio 的一些系统表是比较有用的,比如进行系统反射以及node 信息的查看,同时也便于系统的监控(同时我们也可以基于prometheus 处理) 查询命令 SELECT * …

    技术杂谈 2023年5月30日
    0112
  • <semaphore.h> 和 <sys/sem.h> 的区别

    “semaphore.h” 和 “sys/sem.h”是两种不同的实现并提供不同的功能集 <sys sem.h><…

    技术杂谈 2023年7月24日
    071
  • 小熊飞桨练习册-07PaddleX寻找火箭车车

    小熊飞桨练习册-07PaddleX寻找火箭车车 简介 小熊飞桨练习册-07PaddleX寻找火箭车车,是学习目标检测小项目,本项目开发和测试均在 Ubuntu 20.04 系统下进…

    技术杂谈 2023年7月23日
    088
  • Vogue Shopify主题模板配置修改

    Vogue是一个书样式外观高度可视化产品的Shopify主题,可以创造奢华的购物体验,提升您的品牌和销量。 Vogue Shopify主题特色 针对大图像进行了优化 在整个商店中展…

    技术杂谈 2023年5月31日
    089
  • SETTLE约束算法中的坐标变换问题

    技术背景 在之前的两篇文章中,我们分别讲解了SETTLE算法的原理和基本实现和SETTLE约束算法的批量化处理。SETTLE约束算法在水分子体系中经常被用到,该约束算法具有速度快、…

    技术杂谈 2023年7月25日
    068
  • 防火墙NAT配置与DHCP下发

    该实验如果有做的不足的地方请见谅 实验目标: 按要求划分区域,公司内部办公区为trust,服务器区为dmz,外部网络为untrust。 PC1和PC2为公司内部办公区,需要从防火墙…

    技术杂谈 2023年6月21日
    081
  • 10个开源WEB后台管理系统

    vue-Element-Admin vue-element-admin 是一个后台前端解决方案,它基于 vue 和 element-ui实现。它使用了最新的前端技术栈,内置了 i1…

    技术杂谈 2023年5月30日
    082
  • Golang实现set

    Golang语言本身未实现set,但是实现了map golang的map是一种无序的键值对的集合,其中键是唯一的 而set是键的不重复的集合,因此可以用map来实现set 由于ma…

    技术杂谈 2023年6月21日
    070
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球