zoukankan      html  css  js  c++  java
  • C#学习之事件

    .NET的事件模型是建立在委托的机制上,事件机制可以做到,原生的委托也都可以做到;可以说,事件只是对委托的封装,使得用起来更安全。

    在具体的代码里,定义一个委托和定义一个事件的差别仅仅是:定义事件时要前面加一个 event 关键字!

    正因为这个关键字,编译器就会为这个被封装了的委托暗地里做很多事情,如原生委托可以直接用new来初始化,可以在委托链绑定了很多方法的时候直接用一个 = 操作符来把那些方法清空,等等,而对于事件,编译器把这些都封装了,不能乱来,编译器只是提供了两个方法:add_myEvent、remove_myEvent 让事件客户端仅能通过 += 、 -= 来添加、移除事件的订阅者,如果没有订阅者(也就是委托链为空)时触发事件,那什么也不会发生,等等

    一切尽在代码,不废话了

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.IO;
     6 using System.Threading;
     7 
     8 
     9 namespace test
    10 {
    11 
    12     //定义消息类
    13     class CalculateEventAgrs:EventArgs
    14     {
    15         public readonly int x, y;
    16         public CalculateEventAgrs(int x, int y)
    17         {
    18             this.x = x;
    19             this.y = y;
    20         }
    21     }
    22 
    23 
    24     //定义事件发布类
    25     class Calculator
    26     {
    27         //定义一个代理类,声明事件委托
    28         public delegate void CalculateEventHandler(object sender, CalculateEventAgrs e);
    29 
    30         //定义事件成员,代理类类型,提供外部绑定
    31         public event CalculateEventHandler MyCalculate;
    32 
    33         //提供受保护的虚方法,可以由子类覆写来拒绝监视
    34         protected virtual void OnCalculate(CalculateEventAgrs e)
    35         {
    36             //如果没有订阅者,什么都不做
    37             if (MyCalculate != null)
    38             {
    39                 //触发事件
    40                 MyCalculate(this, e);
    41             }
    42         }
    43 
    44 
    45         //触发事件方法,也就是事件发生,可以理解为点击一下鼠标等事件
    46         public void Calculate(int x, int y)
    47         {
    48             //生成事件发生时的消息
    49             CalculateEventAgrs e = new CalculateEventAgrs(x,y);
    50 
    51             //通知所有的 事件的注册者
    52             OnCalculate( e);
    53         }
    54         
    55     }
    56 
    57 
    58     //定义事件接收类/事件订阅者/
    59     class CalculatorManager
    60     {
    61         //事件处理函数,可以更改所在类(也就是事件订阅者)的一些属性等
    62         public void Add(object sender, CalculateEventAgrs e)
    63         {
    64             Console.WriteLine(e.x + e.y);
    65         }
    66 
    67         //事件处理函数
    68         public void Subtract(object sender, CalculateEventAgrs e)
    69         {
    70             Console.WriteLine(e.x - e.y);
    71         }
    72     }
    73 
    74 
    75     class Program
    76     {   
    77         static void Main(string[] args)
    78         {
    79             Calculator calculate = new Calculator();//事件发布者
    80 
    81             CalculatorManager cm = new CalculatorManager();//事件订阅者/接收者
    82 
    83           //  calculate.MyCalculate = new Calculator.CalculateEventHandler();
    84 
    85 
    86             calculate.MyCalculate += cm.Add;//订阅事件:cm 这个对象主动去订阅 calculate对象里的MyCalculate事件
    87 
    88             calculate.MyCalculate -= cm.Subtract;//取消订阅:如果委托链里没有这个事件,也不会抛出异常,什么也不做
    89 
    90             calculate.Calculate(100,200);//事件发生
    91 
    92             Console.ReadKey();
    93         }
    94 
    95     }
    96 }

    在83行那里,如果去掉注释再编译的话,会提示错误如下:

    如果用到:calculate.MyCalculate = cm.Add; 这句代码的话也会提示一样的错误。

  • 相关阅读:
    物理机与虚拟机互通
    error while loading shared libraries: libevent-2.2.so.1: cannot open shared object file: No such file or directory
    DateTime.Now.ToFileTime
    洛谷-P2249 【深基13.例1】查找
    洛谷-P3817 小A的糖果
    洛谷-P3612 [USACO17JAN]Secret Cow Code S
    洛谷-P5019 铺设道路
    洛谷-P2437 蜜蜂路线
    洛谷-P1044 栈
    洛谷-P1255 数楼梯
  • 原文地址:https://www.cnblogs.com/zouzf/p/2673638.html
Copyright © 2011-2022 走看看