zoukankan      html  css  js  c++  java
  • 事件与委托

    关于事件与委托,说来惭愧一直没能对事件进行深入的研究,一直以来有人问我事件到底是什么。一般都会从用途上加以说明,未曾研究过其实现机制。最近又看到老赵和脑袋两位对事件的应用扩展,下决心彻底把事件的实现研究了一把。

    由于MSDN含混不清的误导,很多人(包括我以前)认为,其实事件就是一种受限的委托。但实际上不是,事件与委托的关系好比字段与属性的关系。事件实际上是一种委托属性,只不过这个属性重载的不是赋值运算符,而是+=-=运算符。

    我们知道,对于一个属性而言,对他的赋值和取值运算会被转换为两个方法的调用。

    例如obj.A这个属性,则下面的表达式等同于后面的形式:

    obj.A = “aaa”;           obj.set_A( “aaa” );

    string a = obj.A;        string a = obj.get_A();

    而事件也是一样,假设有一个事件obj.E,则下面的表达式也等同于后面的形式:

    obj.E += d;              obj.add_E( d )

    obj.E -= d;              obj.remove_E( d )

    与属性一样,事件也可以被继承甚至重写。事件也可以是虚的和抽象的,理论上事件的addremove也可以是有不同的可见性的。

    与属性一样,抽象和虚的事件,其实就是表现为事件的两个方法addremove是抽象的和虚的。

    但是!事件与属性有一个最明显的不同,也就是属性是必须实现的,事件则是不必的。或者说,事件是最早出现的自动属性。

    与自动属性一样,事件也会创建一个字段来保存对应的委托实例,而这个字段与事件同名且是私有。在C#中,你可以访问到这个字段,因为它真的就是一个字段。

    换言之,当你在C#中写代码时,如果是在类型内部使用类型的事件,其实就是引用到那个自动生成的私有字段。换言之,在类的内部使用事件的时候,你使用的是一个委托字段而不是事件。对这个字段的操作是完全不同于在类的外部使用事件的。 

    当然,一旦事件写了addremove访问器,也就不会被自动实现,也就没有这个私有字段了。同样的,因为这个字段是私有的,所以,在类的外部也是访问不到的。

    扩展阅读(感谢装配脑袋提供):

    1、事件其实是由三个方法addremoveraise组成的。但C#编译器总是不会生成raise方法。

    2、自动事件不同的编译器实现是不同的,例如VB的编译器生成的私有字段是(事件名)Event

  • 相关阅读:
    SoapUI 使用笔记
    git 使用笔记(二)
    git 使用笔记(一)
    jquery 拓展
    hdu 1024 Max Sum Plus Plus (DP)
    hdu 2602 Bone Collector (01背包)
    hdu 1688 Sightseeing (最短路径)
    hdu 3191 How Many Paths Are There (次短路径数)
    hdu 2722 Here We Go(relians) Again (最短路径)
    hdu 1596 find the safest road (最短路径)
  • 原文地址:https://www.cnblogs.com/Ivony/p/1563876.html
Copyright © 2011-2022 走看看