zoukankan      html  css  js  c++  java
  • C#事件的理解

    一、原理

    1、定义:当某一对象达到某种条件或发生某种改变时,将消息及时的通知到其他对象。

    2、事件是一种引用类型,实际上也是一种特殊的委托。

    3、设定一个场景:周末我在床上躺着,当我肚子“咕咕”的叫了的时候,我知道我饿了,然后我就会起床、做饭、吃饭。这里“我饿了”就是一个事件,而“肚子咕咕叫”则触发了这个事件的发生(相当于一个“开关”),而我起床、做饭、吃饭就是这个事件被触发后要进行的一系列动作。

    二、语法规则

    1、事件的语法为:【访问修饰符    event     委托名    事件名】

    2、由事件的语法可知,因为在定义事件的时候需要用到委托名,所以在定义事件之前需要先定义委托。

    3、事件的执行顺序可以是:

    (1)事件触发方法—(调用)—事件方法—(调用)—委托方法—(调用)—底层方法

    (2)事件触发方法—(调用)—事件方法—(调用)—底层方法【将底层方法直接挂载到事件方法上】

    注:这个底层方法是自己起的一个便于理解的名称,就是事件被触发后要进行的一系列动作。

    三、代码示例1(使用委托)

        class Program
        {
            public delegate void Dele();  //定义一个委托类型
            public event Dele setevent;  //定义一个事件
    //----------------------------------------------------------------------
            public static void pullalarm()   //定义三个底层方法
            {         Console.WriteLine("拉起警报");       }
            public static void ReinforceTheWall()
            {           Console.WriteLine("加固城墙");       }
            public static void Updatesolider()
            {            Console.WriteLine("升级士兵");        }
    //----------------------------------------------------------------------------
            public void pushevent() {   //定义一个事件触发方法
                setevent();    //定义一个事件方法,这个方法名需要与事件名一致
            }
    //-----------------------------------------------------------------------------
            static void Main(string[] args)
            {
                Program p = new Program();   //定义一个对象
    
                Dele del = pullalarm;      //多播委托,将底层方法挂载到委托中
                del += ReinforceTheWall;
                del += Updatesolider;
                p.setevent += del;  //将委挂载到事件方法中         
                p.pushevent();  //调用事件触发方法
    //----------------------------------------------------------------------------------
                 //下面是挂载的另一种写法
             //p.setevent = new Dele(pullalarm);//将底层方法挂载到委托中并将委托挂载到事件中,这里的【new Dele(方法名)】相当于【del】,因为底层方法是静态方法
             //p.setevent += new Dele(ReinforceTheWall); 类似于多播委托                                                                  //所以不需要对象调用
             //p.pushevent(); 
    //---------------------------------------------------------------------------                                                       
                Console.ReadKey();
    
            }
        }

    1、代码编写顺序:

       (1)定义委托(Dele)、事件(setevent)、定义底层方法(pullalarm、ReinforceTheWall、Updatesolider);

       (2)定义事件触发方法(pushevent),在事件触发方法中定义事件方法( setevent())(事件方法需要与定义的事件名称相同);

       (3)定义委托变量并将底层方法挂载到委托中( Dele del = pullalarm;),对于多个底层方法可以使用多播委托;

       (4)调用事件并将委托挂载到事件中;

       (5)调用事件触发方法;

    四、代码示例2(底层方法直接挂载到事件上)

       class MainCity {
            public delegate void DeleHandler();  //定义一个委托类型
           public event DeleHandler setevent;  //定义一个事件  ,若使用Action或Func则不用定义委托类型
               public void pushevent() {   //定义一个事件触发方法
                  setevent();    //定义一个事件方法,这个方法名需要与事件名一致
             }
        }
     //-----------------------------------------------------------------------------------
        class Program
        {
            public static void pullalarm()   //定义三个底层方法
            {         Console.WriteLine("拉起警报");       }
            public static void ReinforceTheWall()
            {           Console.WriteLine("加固城墙");       }
            public static void Updatesolider()
            {            Console.WriteLine("升级士兵");        }
    
    //-----------------------------------------------------------------------------
            static void Main(string[] args)
            {          
                MainCity maincity = new MainCity();  //定义MainCity类的实例对象       
                Program p = new Program();   //定义一个对象    
    
                
                //事件定义在外部类中,在调用的时候需要用对象进行调用
                maincity.setevent += pullalarm;                   //将方法挂载到事件上,事件在外部类中只能被挂载方法
                maincity.setevent += ReinforceTheWall ;
                maincity.setevent += Updatesolider;
                maincity.setevent -= ReinforceTheWall;           //去掉挂载到事件上的方法
    
                maincity.pushevent();                                               
                Console.ReadKey();
    
            }
        }

    1、这个示例中没有使用委托,直接用事件去调用底层方法

    2、事件定义在了外部类中,所以需要定义一个外部类对象,然后用外部类对象来调用事件,将底层方法挂载到事件上

    五、事件的使用

    1. 定义事件参数类 XXXEventArgs:封装引发事件时需要由事件源传递给响应者的信息。
    2. 定义委托 :public delegate void XXXEventHandler(XXXEventArgs e);
    3. 定义事件源类:

                    -- 基于委托声明事件 public event XXXEventHandler XXX;

                    -- 在某个方法内部引发事件。

            4.响应者

                    -- 实例化事件源对象。

                    -- 注册方法:对象名.事件名+=方法名;

           【温馨提示:即时第一次注册事件,也使用“+=”操作符(即第一次将方法挂载到事件上也要使用“+=”符号)】

    六、相关事项

    1、事件不可以在外部进行直接调用

    2、事件不可以在外界被清空【即令  event=null  】

  • 相关阅读:
    【Linux高频命令专题(24)】grep
    【PSR规范专题(6)】PSR-7 HTTP消息接口【转】
    【redis专题(10)】KEY设计原则与技巧
    【redis专题(9)】事务
    【redis专题(8)】命令语法介绍之通用KEY
    linux 之 jq
    PHP Rabbitmq 报错Broken pipe
    Laravel 跨框架队列交互
    解决Linux下编译.sh文件报错 unexpected operator Syntax error: word unexpected
    安装QConf 报错及解决方案
  • 原文地址:https://www.cnblogs.com/duoyaduoa/p/12600103.html
Copyright © 2011-2022 走看看