事件

      事件的主要特点是一对多关联,即一个事件源,多个响应者。在具体技术上,     .NET

Framework的事件处理机制是基于多路委托实现的。

8.1事件与多路委托

      先看一个多路委托示例项目  MulticastDelegateLinkExample。

首先定义一个委托:

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.handl ers = System.Delegate.Combine(p.handlers,  new

               MyMultiDelegate(s1.MyMethod)) as  MyMultiDelegate;

      p.handl ers = 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,

为此需要修改 UseMultiDelegateExample项目(参看项目  UseEventExample):

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);

  }

 }

      与前不同之处在于 Publisher类给  handlers字段增加了一个  event关键字,并提供了一个

新的用于激发事件的方法 FireEvent()。

      以下为模拟实现事件响应的代码:

static void Main(string[] args)

{

       Publisher p = new  Publisher();

       Subscriber s1 = new  Subscriber();

       Subscriber s2 = new  Subscriber();

      //声明为事件的委托无法直接调用Combine方法

       //以下两句将无法通过编译

      //p.handl ers = System.Delegate.Combine(p.handlers,

                 new MyMultiDelegate(s1.MyMethod)) as MyMultiDelegate;

       //p.handl ers = 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();

}

      请注意上述代码中被注释掉的代码,它们是无法通过编译的,只能使用+=给  handles

事件追加委托,也只能通过类的公有方法来间接地激发此事件。

      对比以上两个示例,不难看出事件与多路委托其实大同小异,只不过多路委托允许在

事件源对象之外激发事件罢了。

事件小结

      面向对象的软件系统有许多都是事件驱动的,比如 ASP.NET就采用了事件驱动

编程方式。

      所谓事件驱动的开发方式,就是指整个系统包含许多的对象,这些对象可以引发多

种事件,软件工程师的主要开发工作就是针对特定的事件书写代码响应它们。

      .NET事件处理机制建立在委托的基础之上,而这两者都是  ASP.NET技术的基础之一。

因此,必须牢固地掌握好委托和事件这两种编程技术,才能为掌握 ASP.NET技术扫清障碍。

posted on 2015-02-26 14:36  星空丶那一抹流光  阅读(151)  评论(0编辑  收藏  举报

导航