談到事件註冊,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表示式、事件系列”包括: