zoukankan      html  css  js  c++  java
  • 随手复习一下委托:delegate

    先骂个街,天儿太闷了……

      随手复习一下委托,delegate 是一种函数指针,是 .net 提供的一种安全的函数指针,翻译的也很贴切,像是委托人,又像代理人,通过“委托”来执行一些函数而不是直接调用它。因为 C# 中委托被实现为指针链表,所以委托可以加入多个函数,一次性一块儿执行。

      举个花生:小明(中国教育中最频繁出镜的绝对明星,不知为什么,我脑子里直觉般闪现第一个名字就是它,我Kao)要给他妈买酱油(貌似这个例子在多年前我自己的帖子里出现过),妈妈对小明的调用就表示为:

    1 public class 妈妈
    2 {
    3     酱油 Get酱油()
    4     {
    5         var 孩子 = new 小明();
    6         retu 小明.打酱油();
    7     }
    8 }
    小明打酱油

    当妈妈需要酱油时候,可以随时召唤小明去卖,那么如果需要盐呢、醋呢,假设 小明 都提供这样的方法,那么妈妈调用时候不得不这样:

     1 public class 妈妈
     2 {
     3     调料 Get调料()
     4     {
     5         var 多种调料 = new 调料集合();
     6         var 孩子 = new 小明();
     7         调料集合.Add(小明.打酱油());
     8         调料集合.Add(小明.买醋());
     9         调料集合.Add(小明.买盐());
    10         
    11         return 多种调料;
    12     }
    13 }
    小明要买多种调料

    事情到了现在,有两个很明显的问题:

    1. 妈妈直接对小明进行了操作,这不是聪明的编码方式,因为如果妈妈还有闺女小红呢?让小红再去买东西就需要修改大量的妈妈类中的代码,显然很二。

    2. 代码中规定了方法里只能调用小明三个技能,再多加两个或少买一个呢,就必须重新修改源代码了,所以不能做到动态的增减技能。

    说到这里好像跑题去谈如何构建程序了,显然我还没到那个水平,回到委托,如果使用委托,至少可以同时解决这两个主要问题,因为:

    1. 委托是“中间人”,妈妈可以全心关注对委托的控制,比如增加和减少要购买的东西

    2. 委托是“相对抽象”的,妈妈通过委托既可以选择小明去买,也可以选择小红去买,一定程度上的解耦

    用委托改一下,依旧忽略细节,只领会精神:

     1 public class 妈妈
     2 {
     3     delegate 调料 买调料委托();
     4     private 买调料委托 妈妈让孩子去买调料;
     5 }
     6 
     7 public static class 小明
     8 {
     9     public static 调料 打酱油(){}
    10     public static 调料 买醋(){}
    11     public static 调料 买盐(){}
    12 }
    13 
    14 public static class 小红
    15 {
    16     public static 调料 打酱油(){}
    17     public static 调料 买米(){}
    18     public static 调料 买油(){}
    19 }
    妈妈用委托

    妈妈定义了一个“买调料”的委托,只要孩子有和这个委托签名一致的技能,妈妈就可以使用。有了这个基础,妈妈再考虑买调料时候就人性化的多,比如 1 日要买酱油、醋和米,就可以这样:

    1 妈妈让孩子去买调料 = new 买调料委托(小明.打酱油);
    2 妈妈让孩子去买调料 += 小明.买醋();
    3 妈妈让孩子去买调料 += 小红.买米();
    4 妈妈让孩子去买调料();
    妈妈自由组合买东西

    妈妈把分属于两个孩子的三个技能添加到了委托,妈妈只需要运行这个委托,就可以运行一次买到三个东西,2 日妈妈不再需要买米而需要买盐时,就可以这样:

    1 妈妈让孩子去买调料 -= 小红.买米();
    2 妈妈让孩子去买调料 += 小红.买盐();
    去掉米添上盐

    从语法上来说我觉得已经比较人性化了,下面放上两个简单的示意代码,描述一下对委托的增减:

     1         delegate void OnEventDelegate(string text);
     2         OnEventDelegate OnEventHandler;
     3 
     4         private void button1_Click(object sender, EventArgs e)
     5         {
     6             if (OnEventHandler == null)
     7             {
     8                 OnEventHandler = new OnEventDelegate(ShowLabel1);
     9                 OnEventHandler += ShowLabel2;
    10                 OnEventHandler += ShowLabel3;
    11                 OnEventHandler += ShowLabel4;
    12 
    13                 MessageBox.Show(string.Format("delegate object count: {0}", OnEventHandler.GetInvocationList().Count()));
    14             }
    15         }
    16 
    17         private void button2_Click(object sender, EventArgs e)
    18         {
    19             if (null != OnEventHandler)
    20             {
    21                 foreach (var method in OnEventHandler.GetInvocationList())
    22                 {
    23                     MessageBox.Show(string.Format("delegate has method cout: {0}, now remove : {1}", OnEventHandler.GetInvocationList().Count(), method.Method.Name));
    24 
    25                     OnEventHandler -= (OnEventDelegate)method;
    26 
    27                     if (null == OnEventHandler)
    28                     {
    29                         MessageBox.Show("delegate remove all method");
    30                         break;
    31                     }
    32                 }
    33             }
    34         }
    35 
    36         private void button3_Click(object sender, EventArgs e)
    37         {
    38             var timeString = DateTime.Now.Second.ToString();
    39             OnEventHandler(timeString);
    40         }
    对委托的增减操作

    完整示例点击下载

  • 相关阅读:
    微信小程序(三)-事件绑定
    微信小程序(二)-语法学习
    微信小程序(一)-工具创建和结构配置说明 Stable Build
    ============================================ 微信小程序开发学习
    Vue学习笔记-Vue.js-2.X 学习(七)===>脚手架Vue-CLI(路由Router)
    Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明-Babel)
    Vue学习笔记-Vue.js-2.X 学习(五)===>脚手架Vue-CLI(PyCharm)
    linux打包压缩命令汇总
    js中函数之函数名带括号与不带括号的区别
    $_FILES error(笔记)
  • 原文地址:https://www.cnblogs.com/cinlap/p/3822740.html
Copyright © 2011-2022 走看看