訂閱事件
訂閱者向事件添加事件處理程序。對于一個要添加到事件的事件處理程序來說,它必須具有
與事件的委托相同的返回類型和簽名。
- 使用+=運算符來為事件添加事件處理程序,如下面的代碼所示。事件處理程序位于該運
算符的右邊。 - 事件處理程序的規范可以是以下任意一種:
- 實例方法的名稱;
- 靜態方法的名稱;
- 匿名方法;
- Lambda表達式。
例如,下面的代碼為CountedADozen事件添加了3個方法:第一個是實例方法,第二個是實
例靜態方法,第三個是使用委托形式的實例方法。
和委托一樣,我們可以使用匿名方法和Lambda表達式來添加事件處理程序。例如,如下代
碼先使用Lambda表達式然后使用了匿名方法。
//Lambda表達式
incrementer.CountedADozen+=()=>DozensCount++;//匿名方法
incrementer.CountedADozen+=delegate{DozensCount++;}
觸發事件
事件成員本身只是保存了需要被調用的事件處理程序。如果事件沒有被觸發,什么都不會發
生。我們需要確保有代碼在合適的時候做這件事情。
例如,如下代碼觸發了CountedADozen事件。注意如下有關代碼的事項。
- 在觸發事件之前和null進行比較,從而查看事件是否包含事件處理程序。如果事件是null,
則表示沒有事件處理程序,不能執行。 - 觸發事件的語法和調用方法一樣:
- 使用事件名稱,后面跟著參數列表(包含在圓括號中);
- 參數列表必須與事件的委托類型相匹配。
把事件聲明和觸發事件的代碼放在一起便有了如下的發布者類聲明。這段代碼包含了兩個成
員:事件和一個叫作DoCount的方法,該方法將在適當的時候觸發該事件。
class Incrementer
{public event EventHandler CountedADozen; //聲明事件void DoCount(object source,EventArgs args){for(int i=1;i<100;i++)if(i%12==0)if(CountedADozen!=null) //確認有方法可以執行CountedADozen(source,args); //觸發事件}
}
圖15-5中的代碼展示了整個程序,包含發布者類lncrementer和訂閱者類Dozens。代碼中需
要注意的地方如下:
- 在構造函數中,Dozens類訂閱事件,將IncrementDozensCount作為事件處理程序;
- 在lncrementer類的DoCount方法中,每增加12個計數就觸發CountedADozen事件。
class Incrementer //發布者
{public event Handler CountedADozen; //創建事件并發布public void DoCount(){for(int i=1;i<100;i++)if(i%12==0&&CountedADozen!=null)CountedADozen(); //每增加12個計數觸發事件一次}
}class Dozens //訂閱者
{public int DozensCount{get;private set;}public Dozens(Incrementer incrementer){DozensCount=0;incrementer.CountedADozen+=InCrementDozensCount; //訂閱事件}void InCrementDozensCount(){DozensCount++; //聲明事件處理程序}
}class Program
{static void Main(){InCrementer incrementer=new Incrementer();Dozens dozensCounter=new Dozens(incrementer);incrementer.DoCount();Console.WriteLine("Number of dozens={0}",dozensCounter.DozensCount);}
}