c# Delegate 和 Events

2021-03-12 05:26

阅读:539

标签:删除   基于   net   may   nbsp   char   lan   ice   就是   

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

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

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

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

 

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

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注册响应函数。代理可作为模块间解耦,传递调用函数的方法。

 

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

c# Delegate 和 Events

标签:删除   基于   net   may   nbsp   char   lan   ice   就是   

原文地址:https://www.cnblogs.com/mosakashaka/p/12607929.html


评论


亲,登录后才可以留言!