国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

C#委托,事件理解入門

黃舟
發(fā)布: 2016-12-21 14:54:05
原創(chuàng)
1124人瀏覽過

目錄?

l????????導(dǎo)論?

l????????什么是委托?

l????????事件的理解?

l????????事件 關(guān)鍵字?

l????????最后?

??

導(dǎo)論?

????在學(xué)習(xí)c#中的委托和事件過程中,我讀了許多文章來理解他們二者究竟是怎么一回事,以及如何使用他們,現(xiàn)在我將整個(gè)的理解過程陳述以下,我學(xué)到的每一方面,恐怕也是你們需要掌握的 :-)。?

什么是委托??

????委托和事件這兩個(gè)概念是完全配合的。委托僅僅是函數(shù)指針,那就是說,它能夠引用函數(shù),通過傳遞地址的機(jī)制完成。委托是一個(gè)類,當(dāng)你對(duì)它實(shí)例化時(shí),要提供一個(gè)引用函數(shù),將其作為它構(gòu)造函數(shù)的參數(shù)。?

??每一個(gè)委托都有自己的簽名,例如:delegate int somedelegate(string s, bool b);是一個(gè)委托申明,在這里,提及的簽名,就是說somedelegate 這個(gè)委托 有 string 和 bool 類型的形參,返回一個(gè)int 類型。?

上面提及的:當(dāng)你對(duì)委托實(shí)例化時(shí),要提供一個(gè)引用函數(shù),將其作為它構(gòu)造函數(shù)的參數(shù)。這里要注意了:被引用的這個(gè)函數(shù)必須和委托有相同的簽名。?

看下面的函數(shù):?

private int somefunction(string str, bool bln){...}?

你可以把這個(gè)函數(shù)傳給somedelegate的構(gòu)造函數(shù),因?yàn)樗麄冇邢嗨频暮灻╥n other?words,他們都有相同的形參類型和個(gè)數(shù),并且返回相同的數(shù)據(jù)類型)。?

????somedelegate sd = new somedelegate(somefunction);?

??sd 引用了 somefunction,也就是說,somefunction已被sd所登記注冊(cè),如果你調(diào)用 sd,somefunction 這個(gè)函數(shù)也會(huì)被調(diào)用,記?。何宜f somefunction的含義,后面,我們會(huì)用到它。?

??現(xiàn)在,你應(yīng)該知道如何使用委托了,讓我們繼續(xù)理解事件之旅……?

事件的理解?

我們知道,在c#中:?

l????????按鈕(button)就是一個(gè)類,當(dāng)我們單擊它時(shí),就觸發(fā)一次click事件。?

l????????時(shí)鐘(timer)也是一個(gè)類,每過一毫秒,就觸發(fā)一次tick事件。?


讓我們通過一個(gè)例子來學(xué)習(xí),假定有這樣的情節(jié):?

??現(xiàn)在有一個(gè)counter的類,它有一個(gè)方法 countto(int countto, int reachablenum),該方法表示:在指定的時(shí)間段內(nèi)(0~~countto),當(dāng)?shù)竭_(dá)指定的時(shí)間點(diǎn)reachablenum時(shí),就觸發(fā)一次numberreached事件。?

它還有一個(gè)事件:numberreached,事件是委托類型的變量。意思是:如果給事件命名,用event關(guān)鍵字和要使用的委托類型申明它即可,如下所示:?

public event numberreachedeventhandler numberreached;?

??

在上面的申明中,numberreachedeventhandle 僅是一個(gè)委托,更確切的表示應(yīng)該是:numberreacheddelegate。但是微軟從不這樣認(rèn)為mousedelegate或者paintdelegate,,而是稱謂:mouseeventhandler 或者 painteventhandler。所以?

numberreachedeventhandler 比numberreacheddelegate聽起來更方便一些,ok?好了,讓我們繼續(xù),現(xiàn)在你知道了,在我們聲明事件之前,需要象下面這樣的形式來定義委托:?

public delegate void numberreachedeventhandler(object sender, numberreachedeventargs e);?

現(xiàn)在聲明的委托 numberreachedeventhandle,它有一個(gè)void 返回值,和object,numberreachedeventargs兩個(gè)形參。就像我們?cè)诘谝还?jié)中強(qiáng)調(diào)的那樣,當(dāng)實(shí)例化委托時(shí),作為實(shí)參傳入的函數(shù)也必須擁有和委托同樣的簽名。?

在你的代碼中, 你是否用過painteventargs 或者 mouseeventargs來確定鼠標(biāo)的移動(dòng)位置?是否在觸發(fā)paint事件的對(duì)象中用過graphics 屬性?實(shí)際上,為用戶提供數(shù)據(jù)的類都是繼承于system.eventargs類,就是我們常說的事件參數(shù)類,如果事件不提供參數(shù),就不定義該類。在我們的例子中,我們通過下面的類提供預(yù)期的時(shí)間點(diǎn)。?

public class numberreachedeventargs : eventargs?

{?

????private int _reached;?

????public numberreachedeventargs(int num)?

????{?

????????this._reached = num;?

????}?

????public int reachednumber?

????{?

????????get?

????????{?

????????????return _reached;?

????????}?

????}?

}?

好,有了前面的介紹,讓我們到counter類里面看看:?

namespace events?

{?

????public delegate void numberreachedeventhandler(object sender,?

????????numberreachedeventargs e);?

??

????///

?

????/// summary description for counter.?

????///
?

????public class counter?

????{?

????????public event numberreachedeventhandler numberreached;?

????????

????????public counter()?

????????{?

????????????//?

????????????// todo: add constructor logic here?

????????????//?

????????}?

????????public void countto(int countto, int reachablenum)?

????????{?

????????????if(countto
????????????????throw new argumentexception(?

????????????????????"reachablenum should be less than countto");?

????????????for(int ctr=0;ctr
????????????{?

????????????????if(ctr == reachablenum)?

????????????????{?

????????????????????numberreachedeventargs e = new numberreachedeventargs(?

????????????????????????reachablenum);?

????????????????????onnumberreached(e);?

????????????????????return;//don't count any more?

????????????????}?

????????????}?

????????}?

??

????????protected virtual void onnumberreached(numberreachedeventargs e)?

????????{?

????????????if(numberreached != null)?

????????????{?

????????????????numberreached(this, e);//raise the event?

????????????}?

????????}?

}?

在counter中,如果到達(dá)指定的時(shí)間點(diǎn),就觸發(fā)一次事件,有以下幾個(gè)方面需要注意:?

l????????通過調(diào)用numberreached(它是numberreachedeventhandler委托的實(shí)例)來完成一次觸發(fā)事件。?

numberreached(this, e);??通過這種方式,可以調(diào)用所有的注冊(cè)函數(shù)。?

l????????通過 numberreachedeventargs e = new numberreachedeventargs(reachablenum); 為所有的注冊(cè)函數(shù)提供事件數(shù)據(jù)。?

l????????看了上面的代碼,你可能要問了:為什么我們直接用 onnumberreached(numberreachedeventargs e)方法來調(diào)用numberreached(this,e),而不用下面的代碼呢??

????if(ctr == reachablenum)?

{?

????numberreachedeventargs e = new numberreachedeventargs(reachablenum);?

????//onnumberreached(e);?

????if(numberreached != null)?

????{?

????????numberreached(this, e);//raise the event?

????}?

????return;//don't count any more?

}?

這個(gè)問題問得很好,那就讓我們?cè)倏匆幌耾nnumberreached 簽名:?

protected virtual void onnumberreached(numberreachedeventargs e)?

①你也明白 關(guān)鍵字protected限定了 只有從該類繼承的類才能調(diào)用該類中的所有方法。?

②關(guān)鍵字 virtual 表明了 在繼承類中可以重寫該方法。?

這兩點(diǎn)非常有用,假設(shè)你在寫一個(gè)從counter繼承而來的類,通過重寫onnumberreached 方法,你可以在事件觸發(fā)之前,進(jìn)行一次其他的工作。?

??

protected override void onnumberreached(numberreachedeventargs e)?

{?

????//do additional work?

????base.onnumberreached(e);?

}?

注意:如果你沒有調(diào)用base.onnumberreached(e), 那么從不會(huì)觸發(fā)這個(gè)事件!在你繼承該類而想剔出它的一些其他事件時(shí),使用該方式是非常有用的。?

l????????還要注意到:委托 numberreachedeventhandler 是在類定義的外部,命名空間內(nèi)定義的,對(duì)所有類來說是可見的。?

好,該我們來實(shí)際操作使用counter類了。?

??

在我們簡(jiǎn)單的應(yīng)用程序中,我們有兩個(gè)文本框,分別是:txtcountto和txtreachable:?




下面是btnrun的click事件:?

private void btnrun_click(object sender, system.eventargs e)?

???????{?

???????????if(txtcountto.text == "" || txtreachable.text=="")?

??????????????return;?

???????????ocounter.countto(convert.toint32(txtcountto.text), convert.toint32(txtreachable.text));?

???????}?

??

private void ocounter_numberreached(object sender, numberreachedeventargs e)?

???????{?

???????????messagebox.show("reached: " + e.reachednumber.tostring());?

???}?

??

初始化事件處理的語法如下:?

ocounter = new counter();?

??????????ocounter.numberreached += new numberreachedeventhandler(ocounter_numberreached);?

??????????

現(xiàn)在你明白了你剛才所做的一切,僅僅初始化 numberreachedeventhandler 委托類型的對(duì)象(就像你實(shí)例化其他對(duì)象一樣),注意到 ocounter_numberreached 方法的簽名與我前面提到的相似。?

還要注意我們用的是+= 而不是=;這是因?yàn)槲惺翘厥獾膶?duì)象,它可以引用多個(gè)對(duì)象(在這里是指它可以引用多個(gè)函數(shù))。for example 如果有另外一個(gè)?

和ocounter_numberreached一樣具有相同簽名的函數(shù)ocounter_numberreached2,這兩個(gè)函數(shù)都可以被引用:?

??

ocounter = new counter();?

???????????ocounter.numberreached += new numberreachedeventhandler(ocounter_numberreached);?

???????????ocounter.numberreached += new numberreachedeventhandler(ocounter_numberreached2);?

現(xiàn)在,觸發(fā)一個(gè)事件后,上面兩個(gè)函數(shù)被依次調(diào)用。?

??

視情況而定,如果你想讓ocounter_numberreached2在numberreached事件發(fā)生后不再被調(diào)用,可以簡(jiǎn)單地這樣寫:ocounter.numberreached -= new numberreachedeventhandler(ocounter_numberreached2);?

??

最后???讓我們看一下完整的源代碼,以供參考:?


form1.cs?


using system;?
using system.drawing;?
using system.collections;?
using system.componentmodel;?
using system.windows.forms;?
using system.data;?

namespace events?
{?
????/**//// ?
????/// summary description for form1.?
????///
?
????public class form1 : system.windows.forms.form?
????{?
????????counter ocounter = null;?

????????private system.windows.forms.button cmdrun;?
????????private system.windows.forms.textbox txtreachable;?
????????private system.windows.forms.textbox txtcountto;?
????????private system.windows.forms.label label1;?
????????private system.windows.forms.label label2;?
????????private system.windows.forms.button btnremovedelegate;?
????????/**//// ?
????????/// required designer variable.?
????????///
?
????????private system.componentmodel.container components = null;?

????????public form1()?
????????{?
????????????//?
????????????// required for windows form designer support?
????????????//?
????????????initializecomponent();?

????????????//?
????????????// todo: add any constructor code after initializecomponent call?
????????????//?
????????????ocounter = new counter();?
????????????ocounter.numberreached += new numberreachedeventhandler(ocounter_numberreached);?
????????????ocounter.numberreached += new numberreachedeventhandler(ocounter_numberreached2);?
????????}?

????????/**//// ?
????????/// clean up any resources being used.?
????????///
?
????????protected override void dispose( bool disposing )?
????????{?
????????????if( disposing )?
????????????{?
????????????????if (components != null)??
????????????????{?
????????????????????components.dispose();?
????????????????}?
????????????}?
????????????base.dispose( disposing );?
????????}?

????????windows form designer generated code#region windows form designer generated code?
????????/**//// ?
????????/// required method for designer support - do not modify?
????????/// the contents of this method with the code editor.?
????????///
?
????????private void initializecomponent()?
????????{?
????????????this.cmdrun = new system.windows.forms.button();?
????????????this.txtreachable = new system.windows.forms.textbox();?
????????????this.txtcountto = new system.windows.forms.textbox();?
????????????this.label1 = new system.windows.forms.label();?
????????????this.label2 = new system.windows.forms.label();?
????????????this.btnremovedelegate = new system.windows.forms.button();?
????????????this.suspendlayout();?
????????????//??
????????????// cmdrun?
????????????//??
????????????this.cmdrun.location = new system.drawing.point(16, 72);?
????????????this.cmdrun.name = "cmdrun";?
????????????this.cmdrun.size = new system.drawing.size(48, 23);?
????????????this.cmdrun.tabindex = 2;?
????????????this.cmdrun.text = "run";?
????????????this.cmdrun.click += new system.eventhandler(this.cmdrun_click);?
????????????//??
????????????// txtreachable?
????????????//??
????????????this.txtreachable.location = new system.drawing.point(144, 40);?
????????????this.txtreachable.name = "txtreachable";?
????????????this.txtreachable.size = new system.drawing.size(56, 20);?
????????????this.txtreachable.tabindex = 1;?
????????????this.txtreachable.text = "";?
????????????//??
????????????// txtcountto?
????????????//??
????????????this.txtcountto.location = new system.drawing.point(144, 16);?
????????????this.txtcountto.name = "txtcountto";?
????????????this.txtcountto.size = new system.drawing.size(56, 20);?
????????????this.txtcountto.tabindex = 0;?
????????????this.txtcountto.text = "";?
????????????//??
????????????// label1?
????????????//??
????????????this.label1.autosize = true;?
????????????this.label1.location = new system.drawing.point(16, 16);?
????????????this.label1.name = "label1";?
????????????this.label1.size = new system.drawing.size(51, 13);?
????????????this.label1.tabindex = 3;?
????????????this.label1.text = "count to";?
????????????//??
????????????// label2?
????????????//??
????????????this.label2.autosize = true;?
????????????this.label2.location = new system.drawing.point(16, 40);?
????????????this.label2.name = "label2";?
????????????this.label2.size = new system.drawing.size(99, 13);?
????????????this.label2.tabindex = 4;?
????????????this.label2.text = "reach this number";?
????????????//??
????????????// btnremovedelegate?
????????????//??
????????????this.btnremovedelegate.location = new system.drawing.point(16, 104);?
????????????this.btnremovedelegate.name = "btnremovedelegate";?
????????????this.btnremovedelegate.size = new system.drawing.size(168, 23);?
????????????this.btnremovedelegate.tabindex = 5;?
????????????this.btnremovedelegate.text = "remove second handler";?
????????????this.btnremovedelegate.click += new system.eventhandler(this.btnremovedelegate_click);?
????????????//??
????????????// form1?
????????????//??
????????????this.autoscalebasesize = new system.drawing.size(5, 13);?
????????????this.clientsize = new system.drawing.size(224, 134);?
????????????this.controls.addrange(new system.windows.forms.control[] {?
??????????????????????????????????????????????????????????????????????????this.btnremovedelegate,?
??????????????????????????????????????????????????????????????????????????this.label2,?
??????????????????????????????????????????????????????????????????????????this.label1,?
??????????????????????????????????????????????????????????????????????????this.txtcountto,?
??????????????????????????????????????????????????????????????????????????this.txtreachable,?
??????????????????????????????????????????????????????????????????????????this.cmdrun});?
????????????this.name = "form1";?
????????????this.text = "events";?
????????????this.resumelayout(false);?

????????}?
????????#endregion?

????????/**//// ?
????????/// the main entry point for the?application.?
????????///
?
????????[stathread]?
????????static void main()??
????????{?
????????????application.run(new form1());?
????????}?

????????private void btnrun_click(object sender, system.eventargs e)?
????????{?
????????????if(txtcountto.text == "" || txtreachable.text=="")?
????????????????return;?
????????????ocounter.countto(convert.toint32(txtcountto.text), convert.toint32(txtreachable.text));?
????????}?

????????private void ocounter_numberreached(object sender, numberreachedeventargs e)?
????????{?
????????????messagebox.show("reached: " + e.reachednumber.tostring());?
????????}?
????????private void ocounter_numberreached2(object sender, numberreachedeventargs e)?
????????{?
????????????messagebox.show("reached2: " + e.reachednumber.tostring());?
????????}?

????????private void btnremovedelegate_click(object sender, system.eventargs e)?
????????{?
????????????ocounter.numberreached -= new numberreachedeventhandler(ocounter_numberreached2);?
????????????ocounter.countto(convert.toint32(txtcountto.text), convert.toint32(txtreachable.text));?
????????}?
????}?
}?
??






counter.cs?


??

using system;?

namespace events?
{?
????public delegate void numberreachedeventhandler(object sender, numberreachedeventargs e);?

????/**//// ?
????/// summary description for counter.?
????///
?
????public class counter?
????{?
????????public event numberreachedeventhandler numberreached;?
?????????
????????public counter()?
????????{?
????????????//?
????????????// todo: add constructor logic here?
????????????//?
????????}?
????????public void countto(int countto, int reachablenum)?
????????{?
????????????if(countto ????????????????throw new argumentexception("reachablenum should be less than countto");?
????????????for(int ctr=0;ctr????????????{?
????????????????if(ctr == reachablenum)?
????????????????{?
????????????????????numberreachedeventargs e = new numberreachedeventargs(reachablenum);?
????????????????????onnumberreached(e);?
????????????????????return;//don't count any more?
????????????????}?
????????????}?
????????}?

????????protected virtual void onnumberreached(numberreachedeventargs e)?
????????{?
????????????if(numberreached!=null)?
????????????{?
????????????????numberreached(this, e);?
????????????}?
????????}?
????}?

????public class numberreachedeventargs : eventargs?
????{?
????????private int _reached;?
????????public numberreachedeventargs(int num)?
????????{?
????????????this._reached = num;?
????????}?
????????public int reachednumber?
????????{?
????????????get?
????????????{?
????????????????return _reached;?
????????????}?
????????}?
????}?
}?

?以上就是C#委托,事件理解入門的內(nèi)容,更多相關(guān)內(nèi)容請(qǐng)關(guān)注PHP中文網(wǎng)(www.miracleart.cn)!?

最佳 Windows 性能的頂級(jí)免費(fèi)優(yōu)化軟件
最佳 Windows 性能的頂級(jí)免費(fèi)優(yōu)化軟件

每個(gè)人都需要一臺(tái)速度更快、更穩(wěn)定的 PC。隨著時(shí)間的推移,垃圾文件、舊注冊(cè)表數(shù)據(jù)和不必要的后臺(tái)進(jìn)程會(huì)占用資源并降低性能。幸運(yùn)的是,許多工具可以讓 Windows 保持平穩(wěn)運(yùn)行。

下載
來源:php中文網(wǎng)
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn
最新問題
開源免費(fèi)商場(chǎng)系統(tǒng)廣告
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關(guān)于我們 免責(zé)申明 意見反饋 講師合作 廣告合作 最新更新
php中文網(wǎng):公益在線php培訓(xùn),幫助PHP學(xué)習(xí)者快速成長(zhǎng)!
關(guān)注服務(wù)號(hào) 技術(shù)交流群
PHP中文網(wǎng)訂閱號(hào)
每天精選資源文章推送
PHP中文網(wǎng)APP
隨時(shí)隨地碎片化學(xué)習(xí)
PHP中文網(wǎng)抖音號(hào)
發(fā)現(xiàn)有趣的

Copyright 2014-2025 http://www.miracleart.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號(hào)