zoukankan      html  css  js  c++  java
  • 委托(5)委托和事件

      在面试的时候经常会被问到,委托和事件的联系和区别?之前也一直没有彻底搞明白,下面就来总结一下。

    从一个有趣的需求入手。有三个角色,猫,老鼠和主人,当猫叫的时候,老鼠开始逃跑,主人则从睡梦中惊醒。

    使用事件实现

    如下代码:

     1 namespace ConsoleApplication4
     2 {
     3     class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7             Cat cat = new Cat("");
     8             Mouse mouse1 = new Mouse("老鼠", cat);
     9             Master master = new Master("张三", cat);
    10             //猫叫,通知所有订阅者
    11             cat.CatCry();
    12 
    13             Console.ReadKey();
    14         }
    15     }
    16 
    17     #region18     public class Cat
    19     {
    20         private string name;
    21 
    22         //声明事件
    23         public event EventHandler<CatCryEventArgs> CatCryEvent;
    24 
    25         public Cat(string name)
    26         {
    27             this.name = name;
    28         }
    29 
    30         public void CatCry()
    31         {
    32             //声明事件参数
    33             CatCryEventArgs args = new CatCryEventArgs(name);
    34             Console.WriteLine(args);
    35 
    36             //触发事件
    37             CatCryEvent(this, args);
    38         }
    39     }
    40 
    41     /// <summary>
    42     /// 事件参数
    43     /// </summary>
    44     public class CatCryEventArgs : EventArgs
    45     {
    46         private string catName;
    47 
    48         public CatCryEventArgs(string catName)
    49             : base()
    50         {
    51             this.catName = catName;
    52         }
    53 
    54         public override string ToString()
    55         {
    56             return string.Format("{0}叫了", catName);
    57         }
    58     }
    59     #endregion
    60 
    61     #region 老鼠
    62     public class Mouse
    63     {
    64         private string name;
    65         public Mouse(string name, Cat cat)
    66         {
    67             this.name = name;
    68             cat.CatCryEvent += CatCryEventHandler;//本质上就是往委托链中添加一个方法
    69         }
    70 
    71         //事件处理程序
    72         private void CatCryEventHandler(object sender, CatCryEventArgs e)
    73         {
    74             Console.WriteLine("{0}逃走了:我勒个去,赶紧跑啊!", name);
    75         }
    76     }
    77     #endregion
    78 
    79     #region 主人
    80     public class Master
    81     {
    82         private string name;
    83         public Master(string name, Cat cat)
    84         {
    85             this.name = name;
    86             cat.CatCryEvent += CatCryEventHandler;//本质上就是往委托链中添加一个方法
    87         }
    88 
    89         //事件处理程序
    90         private void CatCryEventHandler(object sender, CatCryEventArgs e)
    91         {
    92             Console.WriteLine("{0}醒了:我勒个去,叫个锤子!", name);
    93         }
    94     }
    95     #endregion
    96 
    97 }

    通过demo可以总结:

    1,定义和使用事件的流程,如下图:

    2,定义事件参数要继承EventArgs,定义事件使用public event EventHandler<CatCryEventArgs> CatCryEvent;

    3,事件使用了观察者模式,有发布,订阅和通知,至于怎么实现的,本质是什么下面会总结到。

    使用委托实现

     1 namespace ConsoleApplication5
     2 {
     3     //声明委托
     4     public delegate void Del1();
     5 
     6     class Program
     7     {
     8         static void Main(string[] args)
     9         {
    10             //创建委托链(链式委托)
    11             Del1 del1 = () => Console.WriteLine("猫叫了");
    12             del1 += () => Console.WriteLine("老鼠逃走了:我勒个去,赶紧跑啊!");
    13             del1 += () => Console.WriteLine("主人醒了:我勒个去,叫个锤子!");
    14 
    15             //调用委托
    16             del1();
    17 
    18             Console.ReadKey();
    19         }
    20 
    21     }
    22 }

     可以看出,其实就是一个链式委托的调用。向链式委托添加了三个方法,调用的时候依次执行。

    事件和委托

    为了弄清彻底弄清事件和委托的关系,我们查看下EventHandler的源代码,如下图。

    看到上图的红色标记了吗?所以,事件是基于委托实现的。总结一下:

    联系:

    1,事件是基于委托实现的,可以通俗地理解为:事件是一种特殊的委托,特殊的地方在于它定义的是一个有两个参数(事件源和事件参数)没有返回值的委托。

    2,当事件的订阅者订阅事件时,本质上是将事件的处理方法加入到委托链中,当事件触发时,委托链中的所有事件处理方法都会被调用。

    区别:

    委托本质是一种自定义类型(class),而事件本质是一个特殊的委托实例(对象)。

  • 相关阅读:
    状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely
    简单几何(推公式) UVA 11646 Athletics Track
    简单几何(四边形形状) UVA 11800 Determine the Shape
    简单几何(求交点) UVA 11437 Triangle Fun
    计算几何模板
    简单几何(相对运动距离最值) UVA 11796 Dog Distance
    简单几何(求划分区域) LA 3263 That Nice Euler Circuit
    覆盖的面积 HDU
    Desert King 最小比率生成树 (好题)
    约会安排 (区间合并)毒瘤题
  • 原文地址:https://www.cnblogs.com/mcgrady/p/6970909.html
Copyright © 2011-2022 走看看