一、委托的概念

在我们学习委托之前,我们来了解下,什么是委托呢?

官方概念:委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似。与 C 中的函数指针不同,委托是面向对象的、类型安全的和保险的。委托的类型由委托的名称定义。

很多初学者都看不懂官方的概念,一脸懵逼。

举个例子吧:有几个小伙伴在外面玩,突然有两个人手机忘记带了,并且两个人家距离很近,其中一个人想要骑车回去拿,另一个不想回去,就委托另一个帮他拿。

其实委托就是一个类型,它所实例化的变量就是委托类型的变量,也可以说委托是一个方法的模板,当我们去掉delegate关键字的时候,就像是一个没有方法体的方法。

二、委托声明语法

  1. delegate <return type> <delegate-name> <parameter list>

三、接下来我们来看下委托三部曲

  1. public class MyDelegate
  2. {
  3. ////1、委托的声明
  4. public delegate void NoReturnNopara();
  5. public static void show()
  6. {
  7. //2、委托的实例化
  8. NoReturnNopara method = new NoReturnNopara(Study);
  9.  
  10. //3、委托的调用
  11. method.Invoke();
  12. }
  13. public static void Study()
  14. {
  15. Console.WriteLine("正在学习delegate!");
  16. }
  17. }

然后我们调用show方法来看一个结果:

结果没毛病。

四、委托的用途

接下来我们来思考下,这样用委托有什么意义呢?还不如直接 MyDelegate.Study(); 这样。

当然我们学习委托并不是简单的像上面一样,上面只是为了便于我们学习了解委托而已。接下来我们来看一个打招呼的例子:

  1. public class MyGreeting
  2. {
  3. public static void GreetingChinese(string name)
  4. {
  5. Console.WriteLine("{0},早上好",name);
  6. }
  7. public static void GreetingEnglish(string name)
  8. {
  9. Console.WriteLine("{0},good morning",name);
  10. }
  11. }

上面是中国人和外国人打招呼的方式,那个问题来了,我们怎么确定打招呼的人是中国人还中外国人呢?简单,我们定义一个枚举然后判断一个不就ok了嘛。

  1. public class MyGreeting
  2. {public static void Greeting(string name,PeopleType type)
  3. {
  4. switch (type)
  5. {
  6. case PeopleType.Chinese: Console.WriteLine("{0},早上好", name);
  7. break;
  8. case PeopleType.English: Console.WriteLine("{0},good morning", name);
  9. break;
  10. }
  11. }
  12. }
  13. public enum PeopleType
  14. {
  15. Chinese,
  16. English
  17. }

这种做法满足了我们的需求。但是我们应该有所发现,这个方法的可扩展性很差,日后我们要是又有一个需求,要添加日本人打招呼,韩国人打招呼怎么办?我们就不得不修改枚举和Greeting这个方法内的代码,真是糟糕逶了。

那么,我们就应该想其它的方法来解决这个问题。从而达到”对扩展开方,对修改封闭“的原则。怎么实现呢?我们可以不管是哪国人,只负责打招呼就好,将打招呼的逻辑做为参数。

首先,我们先定义一个打招呼的委托。

  1. public delegate void DeleGreeting(string name);

然后将这个委托做为参数传给 Greeting(string name,DeleGreeting greeting)  这个方法,让这个方法来调用打招呼。

  1. public static void Greeting(string name,DeleGreeting greeting)
  2. {
  3. greeting.Invoke(name);
  4. }

最后,我们来实例化这个委托,并调用这个方法。

  1. static void Main(string[] args)
  2. {
  3. DeleGreeting method = new DeleGreeting(MyGreeting.GreetingChinese);
  4. MyGreeting.Greeting("张三",method);
  5.  
  6. DeleGreeting method1 = new DeleGreeting(MyGreeting.GreetingEnglish);
  7. MyGreeting.Greeting("lucy", method1);
  8.  
  9. Console.Read();
  10. }

结果如下:

用这种方式实现的话,以后不管你添加多少种国家的打招呼。都不用去改动 Greeting(); 这个方法,只需要扩展一个打招呼的方法就行了。达到”对扩展开方,对修改封闭“的原则。

五、多播委托

接下来我们来看一下什么是多播委托

委托对象可使用 "+" 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。

也就是说,可以将多个方法绑定给同一个委托

  1. DeleGreeting method = new DeleGreeting(MyGreeting.GreetingChinese);
  2. method += new DeleGreeting(MyGreeting.GreetingEnglish);
  3. MyGreeting.Greeting("李四", method);

结果:

c#之委托详解(Delegate)的更多相关文章

  1. C#委托详解(3):委托的实现方式大全(续)

    接上篇(C#委托详解(2):实现方式大全),本篇继续介绍委托的实现方式. 4.Action<T>和Func<T>委托 使用委托时,除了为每个参数和返回类型定义一个新委托类型之外 ...

  2. C#委托详解(2):实现方式大全

    本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等. 接上篇(C#委托详解(1):什么是委托)介绍完什么是委托之后,来看看C ...

  3. C#事件与委托详解

    from https://www.cnblogs.com/sjqq/p/6917497.html C#事件与委托详解[精华 多看看] Delegatedelegate是C#中的一种类型,它实际上是一个 ...

  4. JavaScript 事件委托详解

    基本概念 事件委托,通俗地来讲,就是把一个元素响应事件(click.keydown......)的函数委托到另一个元素: 一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事 ...

  5. C#委托详解(1):什么是委托

    本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等. 什么是委托? 委托是寻址方法的.NET版本,使用委托可以将方法作为参数 ...

  6. c# 委托详解

    1.委托声明 2.委托入门实例 namespace ConsoleApplication1 { public delegate void methodDelegate(string str); cla ...

  7. C# 委托详解(一)

    1.委托简单例子 class eeProgram { // 声明delegate对象 public delegate string CompareDelegate(int a, int b); // ...

  8. C#事件与委托详解【精华 多看看】

    Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类.与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持有与 ...

  9. Kotlin属性委托系统总结与提供委托详解

    属性委托总结回顾: 在前三次已经将Kotlin委托相关的知识点进行了完整的学习了,具体博文如下: https://www.cnblogs.com/webor2006/p/11369019.html h ...

随机推荐

  1. 关于c#中委托与事件的一些理解

    文章目的:作者(初学者)在学习c#的过程中,对事件.委托及其中的“object sender,EventArgs e”一直感觉理解不透,因此在网上找了一些资料,学习并整理出了该篇笔记,希望能将自己的心 ...

  2. 下载windows版本apache网页服务器

    1.进入apache服务器官网http://httpd.apache.org/,这里我们以下载稳定版的httpd 2.4.25为例,点击download. 2.点击链接Files for Micros ...

  3. 64位WIN7上安装11G R2 ,PLSQL的配置方法

    64位WIN7上安装11G R2 ,PLSQL的配置方法:1.       1.1. 去http://www.oracle.com/technetwork/topics/winsoft-085727. ...

  4. AngularJS国际化配置

    AngularJS国际化配置 下载angular-translate 下载zip包:https://github.com/angular-translate/bower-angular-transla ...

  5. 剑指offer(21-25)编程题

    栈的压入.弹出序列 从上往下打印二叉树 二叉搜索树的后序遍历序列 二叉树中和为某一值的路径 复杂链表的复制 21.输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假 ...

  6. Java reflect 反射 0 java对象的三个阶段

  7. 微软URLRewriter.dll的url重写的简单使用

    1.先下载MSDNURLRewriting.zip包,打开代码生成URLRewriter.dll文件: 2.将URLRewriter.dll文件引用到项目中: 3.在web.config文件中  &l ...

  8. java实现插入排序算法 附单元测试源码

    插入排序算法 public class InsertSortTest { /** * @param args */ public static void main(String[] args) { i ...

  9. 设置主外键时 ORA-02298: 无法验证 - 未找到父项关键字 --NOVALIDATE;

    主要原因是: 在添加CONSTRAINT的时候,默认是需要VALIDATE表中的已有数据的. 你要插入的表A里,有外键连接到另一个表B的主键,你在表A的外键列插入的值,在表B的主键列找不到就不能插入. ...

  10. Postgresql 连接更新

    update dbo.m_role_fun a set role_code = b.rsc from (select rsc, fun_code from dbo.m_fun) b where a.f ...