谈到事件注册,EventHandler是最常用的。
EventHandler是一个委托,接收2个形参。sender是指事件的发起者,e代表事件参数。
□ 使用EventHandler实现猜拳游戏
使用EventHandler实现一个猜拳游戏,每次出拳,出剪刀、石头、布这三者的其中一种。
首先抽象出一个被观察者,其中提供了事件,提供了执行事件的方法。
public class FistGame
{
public string FistName { get; set; }
public event EventHandler GuessFist;
public void Start()
{
if (GuessFist != null)
{
GuessFist(this, EventArgs.Empty);
}
}
}
以上,在Start方法内部调用事件GuessFist的时候,实参this代表FistGame类本身。
客户端必须有一个方法和EventHandler的定义保持一致,这样才可以注册到FistGame类的EventHandler事件上。
class Program
{
static void Main(string[] args)
{
FistGame jiandao = new FistGame(){FistName = "剪刀"};
jiandao.GuessFist += GetFistResult;
FistGame shitou = new FistGame() { FistName = "石头" };
shitou.GuessFist += GetFistResult;
FistGame bu = new FistGame() { FistName = "布" };
bu.GuessFist += GetFistResult;
FistGame finalFist = null;
var temp = new Random().Next()%3;
if (temp == 0)
{
finalFist = jiandao;
}
else if(temp == 1)
{
finalFist = shitou;
}
else
{
finalFist = bu;
}
finalFist.Start();
}
static void GetFistResult(object sender, EventArgs e)
{
FistGame fistGame = sender as FistGame;
Console.WriteLine("本次出的拳为:" + fistGame.FistName);
}
}
以上,GetFistResult方法的参数列表符合EventHandler的定义,并且给每个FistGame实例的GuessFist事件注册了该方法。最后,根据随机数来决定采用哪个FistGame实例。
□ 使用EventHandler传递事件参数
首先需要一个派生于EventArgs的类,通过构造函数注入一个枚举状态。
public class FistGameEventArgs : EventArgs
{
public FistEnum CurrentFist { get; private set; }
public FistGameEventArgs(FistEnum currentFist)
{
CurrentFist = currentFist;
}
}
public enum FistEnum
{
jiandao,
shitou,
bu
}
作为被观察者的FistGame来讲,现在需要EventHandler<TEventArgs>泛型来实现。
public class FistGame
{
public string FistName { get; set; }
public event EventHandler<FistGameEventArgs> GuessFist;
public void Start()
{
if (GuessFist != null)
{
GuessFist(this, new FistGameEventArgs(FistEnum.jiandao));
}
}
}
客户端,与EventHandler参数列表一致的GetFistResult方法把事件参数显示出来。
static void Main(string[] args)
{
FistGame jiandao = new FistGame(){FistName = "剪刀"};
jiandao.GuessFist += GetFistResult;
jiandao.Start();
}
static void GetFistResult(object sender, FistGameEventArgs e)
{
FistGame fistGame = sender as FistGame;
Console.WriteLine("从Name属性获得,本次出的拳为:" + fistGame.FistName);
switch (e.CurrentFist)
{
case FistEnum.jiandao:
Console.WriteLine("从事件参数获得,本次出的拳为:剪刀");
break;
case FistEnum.shitou:
Console.WriteLine("从事件参数获得,本次出的拳为:石头");
break;
case FistEnum.bu:
Console.WriteLine("从事件参数获得,本次出的拳为:布");
break;
}
}
}
总结:使用EventHandler委托不仅可以实现事件注册和取消,而且还可以获取事件发起者和事件参数。
“委托、Lambda表达式、事件系列”包括: