• c# Delegate 和 Events


    同样是看过很多次的概念,但是每次不记得到底是搞懂又忘了,还是没有真正搞懂。

    突然想起上次面试的时候也被问到这个问题:

    代理和事件是一样的吗?用在什么场景?

    记得当时回答的是是一样的╮(╯_╰)╭

    今天主要参考这两篇文章,又重新了解了一下:

    https://www.akadia.com/services/dotnet_delegates_and_events.html

    http://csharpindepth.com/Articles/chapter2/events.aspx

      

    代理

    代理利用delegate定义一个函数签名(即函数的参数和返回值)。

    public delegate void MyDelegate (char a, char b);

    后续利用这个定义的“签名”,可以创建一个实例,实例包含了一个或多个同样签名的函数实现。

    或者可以理解成,代理创建了一个自定义的类型,这个类型是一个函数,且具有特定的参数和返回值。

    那么直接调用需要的函数不就可以了吗,为什么需要通过代理来调用?

    有时候某个操作需要使用的函数,可能是其他模块定义传入的,此时通过代理这个类型参数,将函数传递进去。调用者可以无需了解自己调用的实际是哪个函数,只知道该函数需要的参数和返回值即可。

    对于解除模块间耦合很有帮助。

    另外代理支持通过“+”的方式,在一个代理对象中添加多个实例,而调用者仅需调用一次代理对象,所有之前添加的实例都被调用到,是很方便的特性。

    事件

    在窗体程序中,经常也会用到各式各样的事件响应函数,一般是ControlXX_OnXXX这样类型的定义。

    这些响应函数,实际就是以代理的方式配置的。

    如下代理:

    public delegate void MyChangeHandler (
             object clock,
             TimeInfoEventArgs timeInformation
          );
    

    public event MyChangeHandler MyChange;

    事件源(或者说Publisher)定义了MyChange这个事件。

    而事件响应者(或者说Subscriber)通过在像MyChange中,添加自己的MyChangeHandler类型的响应函数,达到注册事件的目的。

    Publisher在事件发生时,会调用MyChange,从而依次调用所有注册的响应函数。

    是不是和代理很像呢。

    事件,个人感觉是某种程度上的代理语法糖。

    实际上编译器(maybe)会为事件定义一个代理实例,同时定义了add和remove方法,调用者向事件注册回调时,实际上就是在给代理添加实例。

    或者可以说事件就是封装了代理。

    他所封装的是代理本身的实例,而只暴露出注册和删除回调的方法(即+和-),这样Subscriber无法修改其他已注册的事件,而只能注册自己的响应函数。

    回到一开始提到的面试问题。

    现在我可能会回答,代理和事件不同,事件基于代理实现,封装了代理实例,只暴露注册/取消注册的方法。事件在Publisher-Subscriber模式中,提供给Subscriber注册响应函数。代理可作为模块间解耦,传递调用函数的方法。

    当然我现在的理解可能也不准确或者不正确,但是至少相比之前更加清晰了~( ̄_, ̄ )

  • 相关阅读:
    HDU5818 Joint Stacks 左偏树,可并堆
    HDU1512 ZOJ2334 Monkey King 左偏树
    BZOJ3626 [LNOI2014]LCA 树链剖分 线段树
    BZOJ4034 [HAOI2015]树上操作 树链剖分
    BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
    BZOJ1968 [Ahoi2005]COMMON 约数研究 数论
    BZOJ2759 一个动态树好题 LCT
    BZOJ3669 [Noi2014]魔法森林 LCT
    HDFS要点
    HDFS(0.20.2)运营中急救方案
  • 原文地址:https://www.cnblogs.com/mosakashaka/p/12607929.html
Copyright © 2020-2023  润新知