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