好久沒學.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、內聯方式:代碼簡潔,使用匿名類型/方法。