事件(多路委托、事件)

事件的主要特点是一对多关联,即一个事件源,多个响应者。在具体技术上,.NETFramework 的事件处理机制是基于多路委托实现的。

public delegate void MyMultiDelegate(int value );//定义委托类型

//事件发布者类
public class Publisher
{
  public MyMultiDelegate handlers; //事件响应者清单,定义委托变量(委托变量可以当做函数来使用)
}
//事件响应者类
public class Subscriber
{
  //事件处理函数
  public void MyMethod(int i )
  {
    Console.WriteLine(i);
  }
}

以下为模拟实现事件响应的代码:
static void Main(string[] args)
{
  //一个事件源对象
  Publisher p = new Publisher();
  //两个事件响应者
  Subscriber s1 = new Subscriber();

  Subscriber s2 = new Subscriber();
  //可以直接调用Delegate类的静态方法组合多个委托
  p.handlers = System.Delegate.Combine(p.handlers, new
  MyMultiDelegate(s1.MyMethod)) as MyMultiDelegate;
  p.handlers = System.Delegate.Combine(p.handlers, new
  MyMultiDelegate(s2.MyMethod)) as MyMultiDelegate;
  //或调用+=运算符组合委托
  //p.handlers += new MyMultiDelegate(s1.MyMethod);
  //p.handlers += new MyMultiDelegate(s2.MyMethod);
  //最简单的写法
  //p.handlers += s1.MyMethod;
  //p.handlers += s2.MyMethod;
  //直接调用委托变量,代表激发事件
  p.handlers(10);
}

上述代码执行到最后一句时,将会调用两个事件响应者s1 和s2 的事件响应函数MyMethod,在控制台窗口输出两个整数:
10
10


上面这个例子中,事件的激发是在Main()函数中引发的(即上述代码的最后一句),而真实的事件不应允许由外界引发,必须由事件源对象自己引发。
为了限制事件的激发只能由事件源对象自己引发,C#引入了一个新的关键字——event,

public delegate void MyMultiDelegate(int value);
//事件发布者类
public class Publisher
{
  public event MyMultiDelegate handlers; //定义一个事件
  //激发事件
  public void FireEvent()
  {
    handlers(10);
  }
}
//事件响应者类
public class Subscriber
{

//事件处理函数
  public void MyMethod(int i)
  {
    Console.WriteLine(i);
  }
}

static void Main(string[] args)
{
  Publisher p = new Publisher();
  Subscriber s1 = new Subscriber();
  Subscriber s2 = new Subscriber();
  //声明为事件的委托无法直接调用Combine方法
  //以下两句将无法通过编译
  //p.handlers = System.Delegate.Combine(p.handlers,
  new MyMultiDelegate(s1.MyMethod)) as MyMultiDelegate;
  //p.handlers = System.Delegate.Combine(p.handlers,
  new MyMultiDelegate(s2.MyMethod)) as MyMultiDelegate;
  //必须使用+=运算符给事件追加委托
  p.handlers+=new MyMultiDelegate(s1.MyMethod);
  p.handlers+=new MyMultiDelegate(s2.MyMethod);
  //声明为事件的委托也不能直接调用,下面这句无法通过编译
  //p.handlers(10);
  //只能通过类的公有方法间接地引发事件
  p.FireEvent();
}

对比以上两个示例,不难看出事件与多路委托其实大同小异,只不过多路委托允许在事件源对象之外激发事件罢了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值