zoukankan      html  css  js  c++  java
  • 说说Delegate和Event

    Delegate和Event,在C#中,常常看到他们在一起使用,这其中有什么奥秘呢,在这里我说说我看到的,我们以下边的代码为例:

     1using System;
     2
     3//Delegate
     4delegate void UpdateDelegate();
     5
     6//Subject
     7class Subject
     8{
     9    public event UpdateDelegate UpdateHandler;
    10
    11    // Methods
    12    public void Attach(UpdateDelegate ud)
    13    {
    14        UpdateHandler += ud;
    15    }

    16
    17    public void Detach(UpdateDelegate ud)
    18    {
    19        UpdateHandler -= ud;
    20    }

    21
    22    public void Notify()
    23    {
    24        if (UpdateHandler != null) UpdateHandler();
    25    }

    26
    27}

    28public class Client
    29{
    30    static void UpdateDelegateMethod()
    31    {
    32        Console.WriteLine("hello world");
    33    }

    34
    35    public static void Main(string[] args)
    36    {
    37        Subject sj = new Subject();
    38        sj.UpdateHandler += new UpdateDelegate(UpdateDelegateMethod);
    39        sj.Attach(new UpdateDelegate(UpdateDelegateMethod));
    40        sj.Notify();
    41    }

    42}
    类Subjuect中的委托(UpdateDelegate)之前有event关键字,它的IL视图为:

    如果我们把委托(UpdateDelegate)之前的event关键字去掉,它的IL视图为:

    两幅图对比之下,我们就会发现,加上Event关键之和去掉Event关键字所产生的IL代码大不相同。
    我们再来看看Main函数中使用的不同
    如果我们去掉委托(UpdateDelegate)之前的event关键字,下边Main方法中的写法都是对的,在编译的时候不会报错。
    1    public static void Main(string[] args)
    2    {
    3        Subject sj = new Subject();
    4        sj.UpdateHandler = UpdateDelegateMethod;
    5        sj.UpdateHandler = new UpdateDelegate(UpdateDelegateMethod);
    6        sj.UpdateHandler += new UpdateDelegate(UpdateDelegateMethod);
    7        sj.Attach(new UpdateDelegate(UpdateDelegateMethod));
    8        sj.Notify();
    9    }
    如果我们在委托(UpdateDelegate)之前加上event关键字
     1    public static void Main(string[] args)
     2    {
     3        Subject sj = new Subject();
     4        //加上event关键字,下边两段代码要报错
     5        //事件“Subject.UpdateHandler”只能出现在 += 或 -= 的左边(从类型“Subject”中使用时除外)
     6        //sj.UpdateHandler = UpdateDelegateMethod;
     7        //sj.UpdateHandler = new UpdateDelegate(UpdateDelegateMethod);
     8        sj.UpdateHandler += new UpdateDelegate(UpdateDelegateMethod);
     9        sj.Attach(new UpdateDelegate(UpdateDelegateMethod));
    10        sj.Notify();
    11    }
    C#中,delegate是multicast的。multicast就是delegate可以同时指向多个函数。一个multicast   delegate维护着一个函数的list,如果我们没有用+=,而是直接把函数指派给了delegate,这样的话,其他已经钩上delegate的函数都被去掉了,从这里我们就可以看出,使用event可以防止我们直接把函数指派给delegate,从机制上保证了delegate函数链不被破坏。
  • 相关阅读:
    【机器学习笔记】EM算法及其应用
    【机器学习笔记】循环神经网络RNN
    【caffe范例详解】
    Caffe on Windows (Visual Studio 2015+CUDA8.0+cuDNNv5)
    【Keras案例学习】 CNN做手写字符分类(mnist_cnn )
    Celery分布式文件队列
    通过nginx+lua或openresty实现web站点的waf功能
    使用docker hub获取kubernetes各个组件的镜像
    使用Ansible快速构建kubernetes1.10.4HA高可用集群
    创建私服maven服务
  • 原文地址:https://www.cnblogs.com/fengfeng/p/825815.html
Copyright © 2011-2022 走看看