事件的含义:
事件类似于异常,因为它们都是有对象引发(抛出),我们可以提供代码来处理事件。
事件需要订阅。订阅一个事件的含义是提供代码,在事件发生时执行这些代码,它们称为事件处理程序。
单个事件可供多个处理程序订阅,在该事件发生时,这些处理程序都会被调用,其中包括引发该事件的对象所在类中的事件处理程序,但事件处理程序也可能在其他类中。
事件处理程序本身都是简单的方法。对事件处理方法的唯一限制是它必须匹配于事件所要求的返回类型和参数。这个限制是事件定义的一部分,由一个委托指定。
要处理事件,需要提供一个事件处理方法来订阅事件,该方法的返回类型和参数应该匹配事件指定的委托。
示例简单的计时器对象引发事件,调用一个处理方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
namespace Ch13Ex01
{
class Program
{
static int counter = 0;
static string displayString =
"This string will appear one letter at a time. ";
static void Main(string[] args)
{
Timer myTimer = new Timer(100);
myTimer.Elapsed +=/* WriteChar;*/ new ElapsedEventHandler(WriteChar);//关联事件和事件处理程序
myTimer.Start();//启动计时器
Console.ReadKey();
}
static void WriteChar(object source, ElapsedEventArgs e)//事件处理程序
{
Console.Write(displayString[counter++ % displayString.Length]);
}
}
}
自定义事件:
在定义事件前,必须先定义一个委托类型,以用于该事件,这个委托类型指定了事件处理方法必须拥有的返回类型和参数。
给事件命名,在声明时,使用event关键字,并指定要使用的委托类型。以这种方式声明了事件后,就可以引发它,方法是按名称来调用它,就好像它是一个其返回类型和参数是由委托指定的方法一样。
自定义事件示例:(此例是C#入门经典第五版的源码,我稍加自己理解后的注释,菜鸟入门,大神绕道)
Program.cs文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ch13Ex02
{
class Program
{
static void Main(string[] args)
{
Connection myConnection = new Connection();
Display myDisplay = new Display();
myConnection.MessageArrived/*事件*/ +=
new EventHandler/*MessageHandler*/(myDisplay.DisplayMessage)/*使用委托关联事件处理程序DisplayMessage*/;
myConnection.Connect();
Console.ReadKey();
}
}
}
Connection.cs文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
namespace Ch13Ex02
{
public delegate void /*MessageHandler*/EventHandler/*使用系统定义的标准委托类型*/(string messageText);//定义委托变量
public class Connection
{
public event /*MessageHandler*/EventHandler MessageArrived;//声明事件
private Timer pollTimer;
public Connection()
{
pollTimer = new Timer(100);
pollTimer.Elapsed/*事件*/ += new ElapsedEventHandler(CheckForMessage);//关联事件和事件处理程序
}
public void Connect()
{
pollTimer.Start();//启动计时器,定时引发事件
}
public void Disconnect()
{
pollTimer.Stop();
}
private static Random random = new Random();
private void CheckForMessage(object source, ElapsedEventArgs e)
{
Console.WriteLine("Checking for new messages.");
if ((random.Next(9) == 0) && (MessageArrived != null))//MessageArrived != null也使用了委托,其含义是事件是否有事件处理程序关联
{
MessageArrived("Hello Mum!");//引发事件,即是调用事件,调用事件的类型和委托声明的类型相同
}
}
}
}
Display.cs文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ch13Ex02
{
public class Display
{
public void DisplayMessage(string message)//事件处理程序
{
Console.WriteLine("Message arrived: {0}", message);
}
}
}