C#事件与委托十分相似,其实事件包含了一个私有委托,所以事件就像是专门用于某种特殊用途的简单委托。
正如上图所示,发布者类Incrementer里面的事件CountedADozen就像一个装方法的容器,这个容器对方法的添加与删除是里面的私有委托来实现的(这里待会儿可以通过代码理解),发布者类Incrementer还有一块触发事件的代码,这段触发事件代码的方法是那个方法容器的引线,只要运行这方法,引线点燃(触发事件的代码开始运行),引爆了容器(事件CountedADozen开始运行委托里面装载的方法,比如图中的IncrementDozensCount( )和DoSomething( )),这样就走完了从触发代码到运行所有订阅者代码的流程。
以下是实现代码:
delegate void Handler();
class Incrementer//发布者
{
public event Handler CountedADozen;
public void DoCount()//触发事件的方法
{
for (int i = 1; i < 50; i++)
{
if (i % 12 == 0 && CountedADozen != null)//每增加12个计数就触发事件一次,私有委托为空就不执行
{
CountedADozen();
}
}
}
}
class Dozens
{
public Dozens(Incrementer incrementer)
{
incrementer.CountedADozen += IncrementDozensCount;//在发布者私有委托里增加方法
}
void IncrementDozensCount()//事件成员被触发时要调用的方法
{
Console.WriteLine("Dozens");
}
}
class SomeOtherClass
{
public SomeOtherClass(Incrementer incrementer)
{
incrementer.CountedADozen += DoSomething;//在发布者私有委托里增加方法
}
public void DoSomething()//事件成员被触发时要调用的方法
{
Console.WriteLine("SomeOtherClass");
}
}
class Program
{
static void Main()
{
Incrementer incrementer = new Incrementer();
Dozens dozensCounter = new Dozens(incrementer);
SomeOtherClass other = new SomeOtherClass(incrementer);
//incrementer.CountedADozen()
incrementer.DoCount();
}
}
运行结果:
事实上委托与事件的使用的本质差距在event这关键字(可见上图代码第三句),在这段代码里面有没有event关键字运行结果都一样,所以这里看不出差别,但是如果把主函数里面注释掉的代码incrementer.CountedADozen()用出来会报错,但是如果把关键字event取消掉就不报错了,这是因为如果不用event这就跟普通委托一样了,是可以直接调用委托,而加了event关键字才称为事件,事件是不能直接调用委托的,必须在发布者内部调用,你会说那么怎么用呢?只能通过发布者内部方法Docount( )去间接调用,不能随意调用也体现了事件更加安全的优点,这正是事件与委托的使用区别。
转载于:https://blog.csdn.net/qq_38650607/article/details/79748589