第11章 委托與事件教材_第1頁
第11章 委托與事件教材_第2頁
第11章 委托與事件教材_第3頁
第11章 委托與事件教材_第4頁
第11章 委托與事件教材_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第11章

委托(代表)與事件11.1委托(代表)11.2事件11.3事件訪問器總結(jié)11.1委托

11.1.1前言

11.1.2定義

11.1.3定義委托對象及實例化

11.1.4用例

11.1.5進一步理解委托

11.1.6

組播(多重)委托返回首頁11.1.1前言什么是委托?

函數(shù)是一個程序運行的代碼段,調(diào)用該函數(shù),相當于執(zhí)行了這段代碼段.

有時,我們需要實現(xiàn)這樣一個功能:

定義一個特殊”變量”,此變量的內(nèi)容為地址,----指向某個函數(shù)的代碼段(首地址);

這樣,當我們”調(diào)用”該”變量”時,程序就跳轉(zhuǎn)到代碼段去執(zhí)行了.

這個特殊”變量”就是C,C++中的函數(shù)的指針

因為一個函數(shù)有簽名有返回值,所以在C#中,我們將此”變量”看成是某個”類”生成的對象,這樣我們把定義的這個”類”稱為:委托(代表,代理,委派)

委托的實質(zhì)委托實質(zhì)上一種類型,即它的地位處于與類(class),結(jié)構(gòu)(struct),枚舉(enum)一樣委托在定義好之后,必須”實例化””對象”才成使用.委托的”對象”可以用作類,結(jié)構(gòu)的數(shù)據(jù)成員看待(“引用類型”)委托的”對象”當然也可以用作方法成員的參數(shù)看待11.1.2定義

delegate

返回類型委托名(形參1,…);例1:delegatevoidRun();//定義了一個叫Run的委托

//Get實例化后的可以代表所有無參數(shù),無返回值那一類的函數(shù)

//如voidMain()voidFun()….

例2:delegateint

Handle(string

str);//定義了一個叫Handle的委托

//它可以指向int

Fun(string

str);//intFun1(stringstr);//…11.1.3

定義委托對象及實例化委托名對象名;對象名=全名.方法名;委托名對象名=new委托名(初始化參數(shù));

例1:publicstaticvoidMain(){Runmain;//定義一個Get類型的變量mainmain=Main;//

main將voidMain()的代碼段指向

//Runmain=newRun(Main);//實例化mainmain();//執(zhí)行Main代碼段,此例將形成死循環(huán)}

注意:1.委托僅僅是一個類型,故一定要定義一個變量才能使用

2.變量在初始時,只需將”方法名”賦給它

3.變量的使用,要把它看成方法的調(diào)用來理解

11.1.4

用例例1:委托對象當成局部變量例用classAPP{

publicstaticvoidMain(){//Runr1;//定義一個Run類型的變量r1

Runr1=newRun(Run1);//實例化r1,并初始r1();//執(zhí)行Run1代碼段

Aa=newA();

r1=a.Fun1;r1();//執(zhí)行了a.Fun1();}publicstaticvoidRun1(){

Console.WriteLine(“inRun1”); }}

classA{

publicvoidFun1(){Console.WriteLine(“inFun1”);}}11.1.4用例例2:委托對象當成類(結(jié)構(gòu))的數(shù)據(jù)成員使用classAPP{

publicstaticvoidMain(){Bb1=newB();b1.r=newRun(b1.Fun1);b1.r();//執(zhí)行了b1.Fun1()b1.r=Run1;b1.r();//相當于執(zhí)行了APP.Run1();}publicstaticvoidRun1(){

Console.WriteLine(“inRun1”); }}

classB{

publicRunr;publicvoidFun1(){Console.WriteLine(“inFun1”);}}11.1.4

用例例3:委托對象有參數(shù)和返回值時的使用classAPP{

publicstaticvoidMain(){Cc1=newC();=“張飛”;c1.Active=hack;

intresult=c1.Active();//執(zhí)行

Console.WriteLine(result);//了解完成情況}publicstaticint

hack(string

str){

Console.WriteLine(“我是:{0}”,str);//完成砍的動作

Console.WriteLine(“我在砍柴”);

int

結(jié)果=0;

return結(jié)果; }}

classC{publicstringname;

publicHandleActive;}11.1.5

進一步理解委托1.委托使動作名詞化,是函數(shù)的進一步抽象

2.委托的出現(xiàn),使程序能完成一些特殊的功能如:delegate菜加工方法(params

原料[]f);class廚師{public加工方法加工;}class菜{…}class原料{publicstring名稱;..}classXX烹調(diào)大全{staticpublic菜煮(params

原料[]f){...}staticpublic菜炒(params

原料[]f){…}staticpublic菜蒸(params

原料[]f){…}}

11.1.5

進一步理解委托

1.委托使動作名詞化,是函數(shù)的進一步抽象

2.委托的出現(xiàn),使程序能完成一些特殊的功能如:classXX飯店{publicstaticvoidMain(){

廚師張三=new廚師();原料魚=new原料();

張三.加工=XX烹調(diào)大全.煮;

菜菜1=張三.加工(魚);//得到了煮魚

張三.加工=XX烹調(diào)大全.炒;

菜菜2=張三.加工(魚);//得到了炸魚//……}}

將加工方法定義成委托的好處:使張三通過”不斷地學習”可以”學會”不同的烹調(diào)方法11.1.5

進一步理解委托3.作為回調(diào)處理方法的一種機制如系統(tǒng)用此方法來接收消息,和處理事件例:delegatevoidHandl(string

發(fā)送人,string消息);

class消息{publicstring消息名;publicHandl

處理;}

class系統(tǒng){

publicstatic消息[]消息箱=new消息[5];publicstaticvoid加入消息隊列(stirng

消息名,Handl

處理方法){//加入消息…}staticvoid處理消息(){//定期檢查消息隊列,有信就調(diào)用相應的處理方法….

執(zhí)行消息箱[i].處理(發(fā)送人1,消息1)}}

class本程序{publicstaticvoidMain(){

系統(tǒng).加入消息隊列(“有我的信”,通知我);}publicstaticvoid通知我(string消息){

console.writeLine(“事情為:”+消息);}注意:本例僅為模擬系統(tǒng)信息處理,,與實際情況差異較大!!!(見P311,E12-6)11.1.6

組播委托(廣播,多播)

多個委托代碼可以聯(lián)合起來,實現(xiàn)執(zhí)行一個委托變量而順序調(diào)用多個代碼段的能力添加委托委托變量=待加入委托變量1+待加入委托變量2+…;委托變量+=待加入委托變量;委托變量+=new委托(方法名);

移除委托變量-=待加入委托變量;委托變量-=new委托(方法名);

例:p311E12-6重要!!!,理解此知識點會更容易理解事件

11.2

事件

11.2.1前言

11.2.2定義和簡單示例11.2.3使用系統(tǒng)定義的類型11.2.1前言

想象一下:生活中的事件歷史

赤壁之戰(zhàn)9.18事變新中國成立我的人生當我XX歲生日,當我大學畢業(yè),我的第一份薪水門被打開,被關(guān)閉按鈕被按下,被放開,正被按下,正被放開在軟件中,為了讓類和類的實例之間更好的通信,C#為我們定義了事件(event)事件是一種對象間傳遞消息的一種方式.通過事件,可以將事件名與具件事件聯(lián)系起來.

如:

每個人都有XX歲生日事件,但是每個人的XX歲生日所發(fā)生的都不相同.每個按鈕都有按下,放開事件,都每個按鈕按下,放開的處理和結(jié)果都不相同.11.2.2定義和簡單示例

事件是類的成員,定義:…修飾符

event

委托類型事件名;….例1:classDoor{publicevent

EventHandlerOpening;//正在開門

public

event

EventHandlerOpened;//已開門publicevent

EventHandlerClosing;//正在關(guān)門publicevent

EventHandlerClosed;//已關(guān)門}例2:classButton{

event

EventHandler

Cliek;//單擊

event

EventHandler

DubClick;//雙擊}

假設(shè):EventHandler

委托原型為

delegatevoidEventHandler();

11.2.2定義和簡單示例進一點完善門類,加入兩個動作:開門關(guān)門例1:class門{publicevent

Event_HandlerOpening;//正在開門

public

event

Event_HandlerOpened;//已開門publicevent

Event_HandlerClosing;//正在關(guān)門publicevent

Event_HandlerClosed;//已關(guān)門

publicvoidOpen(){

if(Opening!=null)Opening();//發(fā)送正在開門消息

//做開門的動作

//…

if(Opened!=null)Opened();//發(fā)送門已被打開的消息 }

publicvoidClose(){

if(Closing!=null)Closing();//發(fā)送正在關(guān)門消息

//做關(guān)門的動作

//…

if(Closed!=null)Closed();//發(fā)送門已被關(guān)閉的消息 }}11.2.2定義和簡單示例如何使用門例1:class房子{publicstatic門前門=new門();;//定義,并實例化一扇門publicstaticvoidMain(){前門.Opening+=newEvent_Handler(OnOpening);//把處理方法掛到Opening方法上去前門.Opened+=newEvent_Handler(OnOpened);//把處理方法掛到Opened方法上去

while(true){

Console.WriteLine(“請輸入動作:0-開門C-關(guān)門q-結(jié)束程序”);

switch(Console.ReadLine()){case“o”: 前門.Open();//開門;break;case“c”: 前門.Close();//關(guān)門;break;case“q”:return;}

} }

publicstaticvoidOnOpening(){

Console.WriteLine(“門正被我打開!”);}publicstaticvoidOnOpened(){

Console.WriteLine(“門已打開!!!”);}….}11.2.2定義和簡單示例修飾符:

訪問修飾符publicprotecedprivateinternal….

其它修飾符newstaticvirtualseadleoverrideabstract

意義:(見類的成員修飾符)事件類型:

事件的類型一定是委托類型;其:1.可以自行定義(見例1,例2);

2.也可以使用系統(tǒng)已定義好的類型;

例:delegatevoidEventHandler(objcet

send,XXXEventArgs

e)

參數(shù):send通常是指引發(fā)事件的對象,

e是用來存放事件發(fā)生時傳送來的數(shù)據(jù)

(注意:類型為XXXEventArgs,均派生于EventArgs,這個系統(tǒng)定義好的類)

返回值void3.也可以按系統(tǒng)的要求,派生參數(shù)e的類型,,以得到不同的委托

11.2.3使用系統(tǒng)定義的委托類型例:進一點改進例1//定義委托

delegatevoidEventHandler(object

send,DoorEventArgs

e);//處理”門”事件可能需要用到的數(shù)據(jù)對象

classDoorEventArgs:EventArgs{publicstringMessage;publicDoorEventArgs(stringm){Message=m;}}11.2.3使用系統(tǒng)定義的委托類型//門的定義

classDoor{publicstring名稱;

publiceventEventHandlerOpening;//正在開門

publiceventEventHandlerOpened;//已開門

publiceventEventHandlerClosing;//正在關(guān)門

publiceventEventHandlerClosed;//已關(guān)門

publicDoor(){}publicDoor(string名){名稱=名;}publicvoidOpen(objectsend){

if(Opnening!=null)

Opening(send,newDoorEventArgs(this.名稱));//Dosomething

if(Opned!=null)

Opened(send,newDoorEventArgs(this.名稱));}publicvoidClose(objectsend){

if(Closeing!=null)

Closing(send,newDoorEventArgs(this.名稱));//Dosomething

if(Closed!=null)

Closed(send,newDoorEventArgs(this.名稱));}}11.2.3使用系統(tǒng)定義的委托類型//事件驅(qū)動的”主程序”class房子

{publicstring名稱;publicDoor大門;public房子(){}public房子(string名){

大門=newDoor("大門");//定義,并實例化一扇門名稱=名;}publicvoidInit(){

大門.Opening+=newEventHandler(OnOpening);//把處理方法掛到Opening方法上去大門.Opened+=newEventHandler(OnOpened);//把處理方法掛到Opened方法上去大門.Closing+=newEventHandler(OnClosing);

大門.Closed+=newEventHandler(OnClosed);}publicvoidOnOpening(objectsend,DoorEventArgse){Console.WriteLine("{0}的{1}正在打開",((房子)send).名稱,e.Message);}publicvoidOnOpened(objectsend,DoorEventArgse){Console.WriteLine("{0}的{1}已打開",((房子)send).名稱,e.Message);}

…}11.2.3使用系統(tǒng)定義的委托類型//底層系統(tǒng)classApp{static房子h;

publicstaticvoidMain(){

Init();//系統(tǒng)初始化

do{Console.WriteLine("************************************************************");Console.WriteLine("請輸入動作:o-開門c-關(guān)門e-清除屏幕q-結(jié)束程序");Console.WriteLine("************************************************************");switch(Console.ReadLine()){case"o":

h.大門.Open(h);break;case"c":

h.大門.Close(h);break;

case"e":Console.Clear();break;case"q":return;}}while(true);}publicstaticvoidInit(){

h=new房子("陳公館");

h.Init();//初始化}}11.3事件訪問器11.3.1前言11.3.2定義11.3.1前言為什么使用事件訪問器?

事件可以理解為是委托的一種特例.

事件在使用上比委托受了一些限制(為了更有意義的使用事件)

1.事件的類的成員,用event定義委托是一種類型,委托的實例才是類的成員

delegatevoidHandle();//委托

classA{publiceventHandleclick;//事件成員

publicHandleFun;//委托成員

}

2.事件僅能用+=-=加掛或脫離方法委托的實例對象可以用=號與方法掛勾,也可以使用+=,也可以使用-=脫勾

click+=newHandle(B.fun);click-=newHandle(B.fun);

Fun=newHandle();Fun=B.fun;Fun=null;Fun+=newHandle(B.fun);Fun-=newHandle(B.fun);Fun+=B.fun;

11.3.1前言為什么使用事件訪問器?3.系統(tǒng)在編譯時會默認為事件添加上事件訪問器而委托的成員卻不會自動添加.

什么是事件訪問器?

將委托實例成員封裝成事件(加掛和移除方法)

//字段與屬性

privateint_a;

publ

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論