zoukankan      html  css  js  c++  java
  • 事件的前世今生,委托和事件关系

        假设没有事件,我们能不能通过委托实现事件的功能?事实上是可以的。下面我们一步一步剖析!先举个例子:

        有这么一个场景,有一个气球(相当于事件、消息的发送者),气球爆炸(相当于触发事件),小孩子听到气球爆炸会吓哭(小孩子相当于一个事件的订阅者)。我们不适用事件,使用委托来完成这个程序。

       第一步:定义一个全局的委托类型, public delegate void BombEventHandler();//定义了一个委托,其实是一个类吧,相当于一个委托类

       第二步:定义气球类(BalloonPublisher),很简单,这个类仅仅用友一个爆炸的方法,爆炸就发出消息,我爆炸了,也就是调用bomb委托

       public class BalloonPublisher   

      {         public BombEventHandler Bomb;//委托类型的变量

                 public void BalloonBomb()

               {

                     if (Bomb != null)

                     {

                        Bomb();//调用委托

                    }

                 }

        }

       第三步:我们实现订阅者,小孩子类,为了简单我们仅仅定义一个被吓哭的方法

     public class ChildrenSubscribe
        {
             //其实订阅委托
            public void OnHearBomb()
            {
                Console.WriteLine("我被爆炸伤吓哭了");
            }
            
        }

    一切定义好了,就等着关联了,客户端进行关联:

          static void Main(string[] args)
            {
               //客户端触发事件,并订阅事件
                BalloonPublisher pb = new BalloonPublisher();
                ChildrenSubscribe sb = new ChildrenSubscribe();
                pb.Bomb += sb.OnHearBomb;  //是不是很熟悉?关键气球爆炸委托和小孩子听到爆炸后的方法
                pb.BalloonBomb();//触发爆炸事件,其实是执行委托
              
            }

           执行结果很明白,当爆炸触发时候,小孩子吓哭这个方法也在这个委托链上所以也就执行了吓哭方法。

           回顾下上面的过程,和事件功能完全一样,说明委托完全可以实现事件的功能!可是为什么会有事件的产生呢?对上面的例子我们可以这么想,气球爆炸是属于气球本身的,与客户端没关系,只有气球才能触发爆炸这个方法,可是我们上面这个例子是可以通过客户端直接触发气球爆炸的,比如 pb.Bomb();直接触发爆炸委托,也能把小孩吓哭。这样就破坏了封装性。这是事件产生的第一个原因。

           假如气球爆炸后,不仅仅引起小孩子哭,还会引起大人寻找那的气球爆炸了,周围的鸟也会飞走等一系列事件。这就需要把这些方法都得加入到委托连pb.Bomb中去。

    如果客户端不小心把把这个委托连弄断了或者改变了,将会引起很大的麻烦,所有订阅的类都失败了。

           为了解决以上问题,事件才应运而生的,其实事件就是对委托的封装罢了,具体内部实现我就不多说了,网上多的是。

    下面给出利用事件完成此功能的程序:其实很简单,把气球类里面的委托换成事件定义即可,这样以后,你在客户端 直接调用pb.BombEvent();是有语法错误的,从而确保了封装性和事件也只能有气球本身触发,与客户端没任何关系

    public class BalloonPublisher

        {

            public event BombEventHandler BombEvent;  //我加了Event的后缀

            public void BalloonBomb()

            {

                if (BombEvent != null)

                {

                    BombEvent();//调用委托            

                 }                    

          }    

    }

     

  • 相关阅读:
    iptables之NAT端口转发设置
    Windows server 2008 R2远程桌面3389端口号修改
    Nginx启动错误:error while loading shared libraries: libpcre.so.1
    sp_change_users_login 'Update_One', '用户名', '登录名';
    Sqlserver 数据库定时自动备份
    ES DSL 基础查询语法学习笔记
    kafka命令使用
    kafka集群中常见错误的解决方法:kafka.common.KafkaException: Should not set log end offset on partition
    快速排序法(双冒泡排序法)
    运算符
  • 原文地址:https://www.cnblogs.com/fuchongjundream/p/3894572.html
Copyright © 2011-2022 走看看