委託、Lambda表示式、事件系列07,使用EventHandler委託

Darren Ji發表於2014-10-02

談到事件註冊,EventHandler是最常用的。

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

20  
以上,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;
            }
        }
    }    

21

 

總結:使用EventHandler委託不僅可以實現事件註冊和取消,而且還可以獲取事件發起者和事件引數。

 

 

“委託、Lambda表示式、事件系列”包括:

委託、Lambda表示式、事件系列01,委託是什麼,委託的基本用法,委託的Method和Target屬性

委託、Lambda表示式、事件系列02,什麼時候該用委託

委託、Lambda表示式、事件系列03,從委託到Lamda表示式

委託、Lambda表示式、事件系列04,委託鏈是怎樣形成的, 多播委託, 呼叫委託鏈方法,委託鏈異常處理

委託、Lambda表示式、事件系列05,Action委託與閉包

委託、Lambda表示式、事件系列06,使用Action實現觀察者模式,體驗委託和事件的區別

委託、Lambda表示式、事件系列07,使用EventHandler委託

相關文章