我自學C#已經3年了,想說紀錄一下學習的過程,並且提供剛入門的夥伴一點方向,所以寫了這篇文章。
對了做一下聲明,以下的內容都是我網路上資料自己分析的,所以內容不一定完全正確,請見諒
一、前言
如果你剛接觸C#,並且從未學過C或C++,
那麼你有可能和我一樣會卡在委派(Delegate)這個語法上。
但委派(Delegate)在C#內隨處可見,
所以了解他,理解他,加入它吧。
二、什麼是委派(Delegate)
- 對於C/C++來說: 委派是函數指標的”升級版”,他可以依照某些約束指向目標方法,幫助我們間接調用
- 對於C#來說: 對C#而言,委派是一層”包裝紙”,他可以將方法包裝成”類”,讓方法當作”數據”使用
有句俗話說"一切皆地址",不管是屬性或方法,他們都存在記憶體中,所以我們可以用"地址"的方式找到方法
然而C#,並沒有支援直接使用地址的方法,所以C#利用類(Class)去包裝方法,讓方法可以當做數據做傳遞
對你沒有聽錯,委派(Delegate)是類(Class)
三、舉例
我相信你還是聽不懂,這裡舉一個例子:
程式 = 玩具工廠, 方法 = 流水線, 委派(Delegate) = 模具(同輸入,輸出類型)
玩具工廠原本有2條流水線,玩具車和玩具飛機的流水線, => 程式有2個方法,MakeToyCar()和MakeToyPlant()
現在,玩具工廠決定增加第3條流水線玩具飛天汽車, => 程式增加方法,MakeFlyCar()
然而,我們打算將玩具飛機和玩具車的導入玩具飛天汽車中, => MakeFlyCar()中需要用到MakeToyCar()和MakeToyPlant()
所以我們可以將玩具飛機和玩具車模型加入到玩具飛天汽車的流水線中 => 將MakeToyCar()和MakeToyPlant()的委派加入MakeFlyCar()中
一般來說方法是不能當作參數使用,但你可以使用委派(Delegate),讓方法變成參數
就結果而言,就像MakeFlyCar()加入了兩個參數MakeToyCar()和MakeToyPlant()
四、聲明
一般來說,最基礎的用法就是
- public delegate void 玩具模具();
- public delegate string 特殊玩具模具(string input);
要注意的點是因為他是類(Class)所以必須放在與類相同等級的地方,雖然放在類裡面也可以
通常委派會使用在各處,所以會用public,但如果用其他的也ok
最後他的輸入和輸出是可以自行定義的,但要注意你定義的格式必須符合你的方法,就像是玩具模具和特殊模具完全不一樣
五、常用委派時機
大部分我們會分成模板方法和回調方法,但其差別在於使用時目的,並沒有分得那麼明確
模板方法 :
利用外部方法(飛機流水線),
取代內部不確定的部分(汽車流水線內的機翼),通常委派無回傳值
回調方法 :
利用內部方法(玩具流水線),
選擇外部方法(飛機流水線或汽車流水線),通常委派有回傳值
五、進階語法
- Action/Function
1. Action為無回傳值的內建委派
Action<string> action = new Action<string>((string input)=>{})
2. Func為有回傳值的內建委派
Func<string,string> function = new Func<string,string>((string input) => {
String output = input;
Return output; })
- Lambda表達式
(input,…) => {內容;}
Method();
2.間接同步
Delegate.Involk();
Delegate2 += Delegate; Delegate2.Involk();
3.隱式異步
Delegate.BeginInvoke(AsyncCallback,object);
4.顯示異步
Thread thread = new Thread(new ThreadStart(Method()));
Task task = new Task(new Action(Method));
2. 可讀性下降,不易擴展
3. 回調+異步+多線程
4. 內存洩漏,性能下降
留言列表