目錄
l        導(dǎo)論
l        什么是委托
l        事件的理解
l        事件 關(guān)鍵字
l        最后
 
 
導(dǎo)論
    在學(xué)習(xí)c#中的委托和事件過(guò)程中,我讀了許多文章來(lái)理解他們二者究竟是怎么一回事,以及如何使用他們,現(xiàn)在我將整個(gè)的理解過(guò)程陳述以下,我學(xué)到的每一方面,恐怕也是你們需要掌握的 :-)。
什么是委托?
    委托和事件這兩個(gè)概念是完全配合的。委托僅僅是函數(shù)指針,那就是說(shuō),它能夠引用函數(shù),通過(guò)傳遞地址的機(jī)制完成。委托是一個(gè)類,當(dāng)你對(duì)它實(shí)例化時(shí),要提供一個(gè)引用函數(shù),將其作為它構(gòu)造函數(shù)的參數(shù)。
  每一個(gè)委托都有自己的簽名,例如:delegate int somedelegate(string s, bool b);是一個(gè)委托申明,在這里,提及的簽名,就是說(shuō)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,也就是說(shuō),somefunction已被sd所登記注冊(cè),如果你調(diào)用 sd,somefunction 這個(gè)函數(shù)也會(huì)被調(diào)用,記住:我所說(shuō) somefunction的含義,后面,我們會(huì)用到它。
  現(xiàn)在,你應(yīng)該知道如何使用委托了,讓我們繼續(xù)理解事件之旅……
事件的理解
 我們知道,在c#中:
l        按鈕(button)就是一個(gè)類,當(dāng)我們單擊它時(shí),就觸發(fā)一次click事件。
l        時(shí)鐘(timer)也是一個(gè)類,每過(guò)一毫秒,就觸發(fā)一次tick事件。
讓我們通過(guò)一個(gè)例子來(lái)學(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聽(tīng)起來(lái)更方便一些,ok?好了,讓我們繼續(xù),現(xiàn)在你知道了,在我們聲明事件之前,需要象下面這樣的形式來(lái)定義委托:
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ù)也必須擁有和委托同樣的簽名。
 在你的代碼中, 你是否用過(guò)painteventargs 或者 mouseeventargs來(lái)確定鼠標(biāo)的移動(dòng)位置?是否在觸發(fā)paint事件的對(duì)象中用過(guò)graphics 屬性?實(shí)際上,為用戶提供數(shù)據(jù)的類都是繼承于system.eventargs類,就是我們常說(shuō)的事件參數(shù)類,如果事件不提供參數(shù),就不定義該類。在我們的例子中,我們通過(guò)下面的類提供預(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>
    /// summary description for counter.
    /// </summary>
    public class counter
    {
        public event numberreachedeventhandler numberreached;
        
        public counter()
        {
            //
            // todo: add constructor logic here
            //
        }
        public void countto(int countto, int reachablenum)
        {
            if(countto < reachablenum)
                throw new argumentexception(
                    "reachablenum should be less than countto");
            for(int ctr=0;ctr<=countto;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        通過(guò)調(diào)用numberreached(它是numberreachedeventhandler委托的實(shí)例)來(lái)完成一次觸發(fā)事件。
numberreached(this, e);  通過(guò)這種方式,可以調(diào)用所有的注冊(cè)函數(shù)。
l        通過(guò) numberreachedeventargs e = new numberreachedeventargs(reachablenum); 為所有的注冊(cè)函數(shù)提供事件數(shù)據(jù)。
l        看了上面的代碼,你可能要問(wèn)了:為什么我們直接用 onnumberreached(numberreachedeventargs e)方法來(lái)調(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è)問(wèn)題問(wèn)得很好,那就讓我們?cè)倏匆幌耾nnumberreached 簽名:
protected virtual void onnumberreached(numberreachedeventargs e)
①你也明白 關(guān)鍵字protected限定了 只有從該類繼承的類才能調(diào)用該類中的所有方法。 
②關(guān)鍵字 virtual 表明了 在繼承類中可以重寫(xiě)該方法。
這兩點(diǎn)非常有用,假設(shè)你在寫(xiě)一個(gè)從counter繼承而來(lái)的類,通過(guò)重寫(xiě)onnumberreached 方法,你可以在事件觸發(fā)之前,進(jìn)行一次其他的工作。
 
 
protected override void onnumberreached(numberreachedeventargs e)
{
    //do additional work
    base.onnumberreached(e);
}
注意:如果你沒(méi)有調(diào)用base.onnumberreached(e), 那么從不會(huì)觸發(fā)這個(gè)事件!在你繼承該類而想剔出它的一些其他事件時(shí),使用該方式是非常有用的。
l        還要注意到:委托 numberreachedeventhandler 是在類定義的外部,命名空間內(nèi)定義的,對(duì)所有類來(lái)說(shuō)是可見(jiàn)的。
好,該我們來(lái)實(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());
   }
 
 
初始化事件處理的語(yǔ)法如下:
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)單地這樣寫(xiě):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> 
    /// summary description for form1. 
    /// </summary> 
    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; 
        /**//// <summary> 
        /// required designer variable. 
        /// </summary> 
        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); 
        } 
        /**//// <summary> 
        /// clean up any resources being used. 
        /// </summary> 
        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 
        /**//// <summary> 
        /// required method for designer support - do not modify 
        /// the contents of this method with the code editor. 
        /// </summary> 
        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 
        /**//// <summary> 
        /// the main entry point for the application. 
        /// </summary> 
        [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)); 
        } 
    } 
} 
 
using system; 
using system.drawing; 
using system.collections; 
using system.componentmodel; 
using system.windows.forms; 
using system.data; 
namespace events 
{ 
    /**//// <summary> 
    /// summary description for form1. 
    /// </summary> 
    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; 
        /**//// <summary> 
        /// required designer variable. 
        /// </summary> 
        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); 
        } 
        /**//// <summary> 
        /// clean up any resources being used. 
        /// </summary> 
        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 
        /**//// <summary> 
        /// required method for designer support - do not modify 
        /// the contents of this method with the code editor. 
        /// </summary> 
        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 
        /**//// <summary> 
        /// the main entry point for the application. 
        /// </summary> 
        [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)); 
        } 
    } 
} 
 
using system; 
using system.drawing; 
using system.collections; 
using system.componentmodel; 
using system.windows.forms; 
using system.data; 
namespace events 
{ 
    /**//// <summary> 
    /// summary description for form1. 
    /// </summary> 
    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; 
        /**//// <summary> 
        /// required designer variable. 
        /// </summary> 
        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); 
        } 
        /**//// <summary> 
        /// clean up any resources being used. 
        /// </summary> 
        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 
        /**//// <summary> 
        /// required method for designer support - do not modify 
        /// the contents of this method with the code editor. 
        /// </summary> 
        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 
        /**//// <summary> 
        /// the main entry point for the application. 
        /// </summary> 
        [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 
 counter.cs 
  
using system; 
namespace events 
{ 
    public delegate void numberreachedeventhandler(object sender, numberreachedeventargs e); 
    /**//// <summary> 
    /// summary description for counter. 
    /// </summary> 
    public class counter 
    { 
        public event numberreachedeventhandler numberreached; 
         
        public counter() 
        { 
            // 
            // todo: add constructor logic here 
            // 
        } 
        public void countto(int countto, int reachablenum) 
        { 
            if(countto < reachablenum) 
                throw new argumentexception("reachablenum should be less than countto"); 
            for(int ctr=0;ctr<=countto;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; 
            } 
        } 
    } 
} 
  
using system; 
namespace events 
{ 
    public delegate void numberreachedeventhandler(object sender, numberreachedeventargs e); 
    /**//// <summary> 
    /// summary description for counter. 
    /// </summary> 
    public class counter 
    { 
        public event numberreachedeventhandler numberreached; 
         
        public counter() 
        { 
            // 
            // todo: add constructor logic here 
            // 
        } 
        public void countto(int countto, int reachablenum) 
        { 
            if(countto < reachablenum) 
                throw new argumentexception("reachablenum should be less than countto"); 
            for(int ctr=0;ctr<=countto;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; 
            } 
        } 
    } 
} 
using system; 
namespace events 
{ 
    public delegate void numberreachedeventhandler(object sender, numberreachedeventargs e); 
    /**//// <summary> 
    /// summary description for counter. 
    /// </summary> 
    public class counter 
    { 
        public event numberreachedeventhandler numberreached; 
         
        public counter() 
        { 
            // 
            // todo: add constructor logic here 
            // 
        } 
        public void countto(int countto, int reachablenum) 
        { 
            if(countto < reachablenum) 
                throw new argumentexception("reachablenum should be less than countto"); 
            for(int ctr=0;ctr<=countto;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; 
            } 
        } 
    } 
}