有關(guān)事件與委托關(guān)系的思考
事件與委托究竟是什么關(guān)系,你了解么?你了解的正確么?這樣的基礎(chǔ)概念,其實往往是容易造成混淆的地方。下面介紹Ivony對事件與委托關(guān)系的思考總結(jié),總結(jié)的還是挺不錯的。
由于MSDN含混不清的誤導(dǎo),很多人(包括我以前)認為,其實事件就是一種受限的委托。但實際上不是,事件與委托的關(guān)系好比字段與屬性的關(guān)系。事件實際上是一種委托屬性,只不過這個屬性重載的不是賦值運算符,而是+=和-=運算符。
我們知道,對于一個屬性而言,對他的賦值和取值運算會被轉(zhuǎn)換為兩個方法的調(diào)用。
例如obj.A這個屬性,則下面的表達式等同于后面的形式:
- obj.A = “aaa”; obj.set_A( “aaa” );
- string a = obj.A; string a = obj.get_A();
而事件也是一樣,假設(shè)有一個事件obj.E,則下面的表達式也等同于后面的形式:
- obj.E += d; obj.add_E( d )
- obj.E -= d; obj.remove_E( d )
與屬性一樣,事件也可以被繼承甚至重寫。事件也可以是虛的和抽象的,理論上事件的add和remove也可以是有不同的可見性的。
與屬性一樣,抽象和虛的事件,其實就是表現(xiàn)為事件的兩個方法add和remove是抽象的和虛的。
但是!事件與屬性有一個最明顯的不同,也就是屬性是必須實現(xiàn)的,事件則是不必的?;蛘哒f,事件是最早出現(xiàn)的自動屬性。
與自動屬性一樣,事件也會創(chuàng)建一個字段來保存對應(yīng)的委托實例,而這個字段與事件同名且是私有。在C#中,你可以訪問到這個字段,因為它真的就是一個字段。
換言之,當(dāng)你在C#中寫代碼時,如果是在類型內(nèi)部使用類型的事件,其實就是引用到那個自動生成的私有字段。換言之,在類的內(nèi)部使用事件的時候,你使用的是一個委托字段而不是事件。對這個字段的操作是完全不同于在類的外部使用事件的。
當(dāng)然,一旦事件寫了add和remove訪問器,也就不會被自動實現(xiàn),也就沒有這個私有字段了。同樣的,因為這個字段是私有的,所以,在類的外部也是訪問不到的。
【編輯推薦】