日期:2014-05-17  浏览次数:21159 次

浅析C#之——Observer, Delegate和event(3)

接下来说一下event

event的简述:

event是C#特有的一个修饰符关键字语法本质是进行一个转换,实现对delegate的进一步封装。

?

event的简单使用方法:

之前介绍过了delegate,那么event的语法其实很简单,就只要在之前的Observer_delegate.cs中的delegate申明行中加入一个event修饰符即可,其它地方一个字都不用改就能编译通过运行结果毫无差别。

?

//private ReceiverList receiverList; //has a delegate;	
private event ReceiverList receiverList; //申明一个事件;

?

event的事实真相:

用ILDasm查看经过编译后的Observer_event.exe,结果如下:



可以看到,编译器是将event修饰过的那一行代码转换成了一个私有委托的申明和两个对其进行add和remove操作的函数,最后还有一个针对私有委托的包装。

私有委托的申明不说了,就等于是这样一行代码:

?

 private ReceiverList receiverList = null; 

?

add_receiverList()和remove_receiverList()方法的本质是对Delegate的Combine方法和Remove方法进行了封装,以循环和对CompareExchange的调用实现了一种线程安全的添加和移除委托的方式。

而最后的那个包装:



?我们可以将其与一个属性的IL代码进行比较:


可以发现两者非常相似。所以我的理解是,event修饰符所做的,除了帮我们在底层申明私有委托字段和线程的add,remove方法外,还将委托字段做成类似于属性的样子,类内部可以随意访问,类外部默认只能通过那两个函数访问(当然你也可以在类申明时添加自己对于委托字段的操作方法供外部调用,如我们在代码中所写的addReceiver和removeReceiver方法)。

这也可以看出,C#是希望我们能将event当做一个类的属性来看待,默认支持的操作也是只允许该属性作为+=和-=操作符的左值出现,一切都是为了简化。

?

event的应用——Eventlistener设计模式:

先前提到过一个Observer设计模式。我原本以为event也是多用于这种设计模式的,后来才发现,其实C#提出这个字段的本意更应该是推崇Event-Listener事件侦听设计模式。

两者没有进行过深入的比较分析,大致了解了一下发现,Observer和Eventlistener非常相像:Observer中主题和观察者对应于Eventlistener中的事件源和事件侦听者。

如果将发送消息的一方成为服务端,接收消息的一方称为客户端的话,那么Observer给我的感觉就是更重视服务端,更多的操作会在服务端完成,而则Event-Listener更重视客户端;

但其实这也只是我比较浅薄的感觉,还望高人指点蛤……

?

接下来打算用Eventlistener设计模式重新设计一下先前的机制,因为模式变了,所以类和方法名会做一些变化以更切合设计模式的表现。

?

// TODO。。。。。。。

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?