深入理解事件(event)與委托(delegate)


好久沒學.NET了,最近重又開始學習,發現委托有很多變化了,發現事件不明白了(可能以前就沒明白過)

網上搜索了幾篇文章,也沒注意什么時候的,發現都講的不徹底,綜合一下,也當個學習筆記。

using System;

namespace Test
{
    class Sender
    {
        // 委托的定義有多種方式
        // 方式 A:一般委托:TheType 可復用
        // public delegate void TheType(object sender, EventArgs e);
        // public TheType OnRunEnd;

        // 方式 B:一般委托:內聯方式
        public Action<object, EventArgs> OnRunEnd;

        // 方式 C:特殊委托:事件,需用 event 修飾
        // public event Action<object, EventArgs> OnRunEnd;

        public void Run()
        {
            Console.WriteLine("Sender Run");

            // 委托的調用也有多種方式
            // 方式一:
            // if (OnRunEnd != null)
            // {
            //     OnRunEnd(this, new EventArgs());
            // }

            // 方式二:VS自動提示用方式二替代方式一
            OnRunEnd?.Invoke(this, new EventArgs());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Sender s = new Sender();

            // 委托的賦值有多種方式
            // 方式 1:The_OnRunEnd要求是靜態方法或實例方法的引用
            // s.OnRunEnd += new Action<object, EventArgs>(The_OnRunEnd);

            // 方式 2:方式一簡化,可以認為是同一種,The_OnRunEnd 可復用
            // s.OnRunEnd += The_OnRunEnd;

            // 方式 3:內聯方式
            // s.OnRunEnd += delegate (object sender, EventArgs e) { Console.WriteLine("Sender Run End"); };

            // 方式 4:內聯方式,拉姆達表達式,看上去就是方式三的演化
            s.OnRunEnd += (sender, e) => { Console.WriteLine("Sender Run End"); };

            s.Run();

            // 事件與委托的關鍵區別就在此了
            // 如果是“方式 C”定義的事件委托以下語句編譯出錯,這說明了:
            // 使用 event 可以保障 OnRunEnd 只能在 Class Sender 內部調用
            s.OnRunEnd(null, new EventArgs());

            Console.ReadKey();
        }

        // 照顧“方式 1”,“方式 2”定義的方法
        static void The_OnRunEnd(object sender, EventArgs e)
        {
            Console.WriteLine("Sender Run End");
        }
    }
}

這樣看來,問題其實很簡單:
事件是特殊的委托,它遵循一些約定:
1、它用 event 關鍵詞申明;
2、它有固定的簽名:object參數,EventArgs或派生類參數,無返回值;
3、只能由定義它的類內部調用。

倒是委托的定義、賦值寫法較多,讓我迷糊過,歸納一下,其實都是兩種:
1、可復用方式:代碼略多些,需定義顯示類型/方法;
2、內聯方式:代碼簡潔,使用匿名類型/方法。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM