c# 委派(delegate) 介紹

什麼是委派(Delegate)?

Delegate其實就是指向函數的指標(Pointer)

使用面向很廣,但其中一個特別重要的是用來當作EventEventHandler之間的傳遞橋梁(Pipeline)

延伸閱讀: C# 事件(Event) 介紹

聽到指向函數的指標可能還是有點模糊,這邊用按鈕的例子來解釋。

假設一個按鈕Button綁定了ClickEvent,當ClickEvent被觸發時,會呼叫SomeMethod

阿要怎麼呼叫呢? 就是要通過Delegate拉~

Delegate實作方式

如果要自己定義委派方法,要使用delegate關鍵字:

// Delegate
public delegate void WorkPerformedHandler(int hours, WorkType workType);

public enum WorkType
{
    GoToMeetings,
    Golf,
    GenerateReports
}

剛剛有提到Delegate其實就是一個傳遞的橋樑,所以上面的例子只是把hourworkType這兩個資料透過WorkPerformedHandler這個方法傳遞給接收者,接收者必須要有相同數量及型別的參數(變數名稱不受限制):

// Handler
public void WorkPerformed1(int workHours, WorkType wtype) 
{
    Console.WriteLine("WorkPerformed1 called");
}

那要怎麼把Delegate跟Handler綁在一起呢?只要把Delegate的方法傳入Handler就好!

// Delegate Instance
WorkPerformedHandler del1 = new WorkPerformedHandler(WorkPerformed1);

而要呼叫del1的委派方法時,只要傳入跟WorkPerformedHandler一樣的參數就好:

del1(5, WorkType.Golf):

加入更多方法到調用列表(Invocation List)

委派只能綁定一種方法嗎? 其實他是可以綁定複數個方法的!

因為Delegate類別繼承了MulticastDelegate這個類別,內部實現了InvocationList來達到多點傳送

也就是說只要有一個新的委派方法傳進來就會被加入InvocationList裡,而每次Handler被呼叫時會自動呼叫InvocationList裡所有的委派方法。

實作方式:

WorkPerformedHandler del1 = new WorkPerformedHandler(WorkPerformed1);
WorkPerformedHandler del2 = new WorkPerformedHandler(WorkPerformed2);

// 加入至InvocationList
del1 += del2;

// del2也會被呼叫到
del1(5, WorkType.GoToMeetings);

另外我們也可以把Handler傳入某個方法的參數中,藉由呼叫該方法來呼叫Handler所綁定的委派方法,例如:

static void DoWork(WorkPerformedHandler del) 
{
    del(5, WorkType.GoToMeetings);
}

本文是我在Pluralsight上的課C# Events, Delegates and Lambdas時所作的筆記,有興趣可以看看