订阅事件
订阅者向事件添加事件处理程序。对于一个要添加到事件的事件处理程序来说,它必须具有
与事件的委托相同的返回类型和签名。
- 使用+=运算符来为事件添加事件处理程序,如下面的代码所示。事件处理程序位于该运
算符的右边。 - 事件处理程序的规范可以是以下任意一种:
- 实例方法的名称;
- 静态方法的名称;
- 匿名方法;
- 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);
}
}