如何理解委托与事件
如何理解委托与事件
从事C#工作者,只有理解了委托和事件其中的奥秘,才算得上C#入门。我认为,只有懂得了什么是委托,如何用委托链制造事件,才算正式进入了C#的世界。否则,你只是一个C语言编程者。
1.什么是委托
委托,其实质是一个函数指针,但在C#中,本着万物皆对象的原则,委托是一个类(故可以写在命名空间里面),通过IL代码可以看出,委托有自己的构造函数与成员函数。
在程序中使用委托,通常分为3个部分,定义委托,定义委托相当于为委托写好了一个标签;实例化委托,实例化委托对象相当于给一个对象贴上标签,同时实例本身也符合标签定义;方法处理器,实例化的委托对象中就将方法名(指针)当构造参数传入对象,此时,应该将方法处理器具体执行步骤编码实现。
委托在程序中,有3大作用:
- 跨线程调用方法,例如,子线程跨到主线程UI去操作其控件;
- 将一种委托方法(行为)作为一个函数参数进行传递;
- 构造委托链,进行链式执行方法,实现跨窗体、类库传递行为方法的一种方式。
2.什么是事件
想要更加深入地去理解委托,那么我们就该去了解什么是事件了。在C#中,控件触发的事件,随处可见,可大部分新手,其实并不知道事件的本质是什么,也不知自己又如何去定义一个事件。其事件的本质是一个多路广播委托链的实例对象。此处,重点强调,事件是一个已经被实例化的对象(故只能写在类里面)。虽然事件本质上是委托,但也同时与委托有着实质区别。
在程序中,我们自己去定义一个事件,通常也是分为3个部分,定义委托,此处也可以使用预定义委托类型EventHandler,两者的区别在于,自定义委托,是自己来写这个委托的标签(即返回值以及函数参数),而EvenHandler委托,默认无返回值,传入sender和EventArgs两个参数;发布事件,将委托定义好标签后,便需要将委托标签发布出去,从而定义成事件,事件的形式与委托形式相同(其本质将其实例化委托对象);订阅事件,在实例化的委托对象(即事件)添加函数方法即可完成订阅。
3.多路广播委托链与事件的区别
看了这么多,想必大家也明白了委托与事件的关系。但多路广播委托链与事件到底又有何区别呢?微软在.NET的平台上,最喜欢做的一件事,就是不断地优化程序底层代码,来让程序员更多地关注程序业务逻辑。其实,事件的本质就是多路广播委托链的一种结构式封装。
多路广播委托链与事件有两点区别:
- 多路广播委托链,需要用一个委托去实例化;而事件定义后,便不需要所谓的实例化(其本质是将委托对象实例化)。
- 多路广播委托链,在添加新的委托时,需要实例化一个委托而后进行添加;而事件定义后,进行订阅事件,只需要添加函数方法即可(其本质是将一个实例化委托添加)。
如何还想对委托和事件有更深入地更直接地理解,可以自己定义委托和事件,去查看IL代码,分析其运行的本质。