委託: delegate
1.什麼是委託
delegate(委託)是一種特殊的類,用來定義一羣【具有共同特徵】的方法;這些方法作用於相同類型和順序的參數, 但不確定具體的執行方式;
對於每一個委託的實例,你可以將具體的方法掛載(+=)到委託實例上,使該委託實例獲得具體的執行方式。
哈,我猜,你很可能完全聽不懂前面我說了什麼。事實上,絕大多數相關資料中對委託的解釋,比我剛纔說的還要晦澀難懂。
所以——來聽我講故事吧!
【將故事中的各段代碼拼接起來,即可編譯執行。】
2.講故事時間到!
某村莊深受強盜(Robber)的困擾。村長在告示牌上張貼了懸賞委託Eliminate:想辦法消除兩名強盜Tom和Bob的威脅。
但村長沒有對【委託:消除強盜威脅】的具體方法作出要求;如何對付強盜呢?這將由接下委託的勇士們自己考量。
namespace delegateShow
{
public class Robber
{
public string name;
public Robber(string str)
{
name = str;
}
}
public delegate void Eliminate(Robber robber);
有一位戰士看到了委託。戰士擁有Kill(Robber x)能力,可以殺死強盜;
戰士不假思索地揭走了一張委託,將其作爲自己的任務eliminate。
public class Warrior
{
public Warrior()
{
Console.WriteLine("我是戰士");
}
public void Kill(Robber x)
{
Console.WriteLine("我殺死了強盜" + x.name);
}
public Eliminate eliminate = null;//戰士接下了委託,將其變成了自己的方法eliminate,具體執行方式尚未確定
}
有一位詩人也看到了委託。詩人擁有Persuade(Robber x)能力,可以勸服強盜;
詩人也覺得胸有成竹,於是也揭走一張委託,將其作爲自己的任務eliminate。
public class Poet
{
public Poet()
{
Console.WriteLine("我是詩人");
}
public void Persuade(Robber x)
{
Console.WriteLine("我勸服了強盜" + x.name);
}
public Eliminate eliminate = null;//詩人接下了委託,將其變成了自己的方法eliminate,具體執行方式尚未確定
}
兩名強盜Tom和Bob出現了。戰士warrior和詩人poet各自出發,戰士去處理強盜Tom,詩人去處理強盜Bob。
戰士認爲,執行委託Eliminate的方法應該是殺死強盜。
詩人認爲,執行委託Eliminate的方法應該是勸服強盜。
於是,他們各自拿定了主意,並以自己的方式執行委託——
戰士殺死了強盜Tom,詩人勸服了強盜Bob.
雖然戰士和詩人執行委託的方式大不相同,但都符合村長所貼出委託的要求,因此他們都完成了任務。
public class MainClass
{
static void Main(string[] args)
{
//兩名強盜出現
Robber Tom = new Robber("Tom");
Robber Bob = new Robber("Bob");
//現在戰士warrior和詩人poet出發了,戰士去處理強盜Tom,詩人去處理強盜Bob
Warrior warrior = new Warrior();//戰士登場
warrior.eliminate += warrior.Kill;
//戰士對自己接下的委託實例eliminate進行了解釋,使得這個委託的具體執行方式變成了戰士的Kill方法——殺死強盜
warrior.eliminate(Tom);//戰士對Tom執行了自己的委託實例eliminate
Poet poet = new Poet();//詩人登場
poet.eliminate += poet.Persuade;
//詩人對自己接下的委託實例eliminate進行了解釋,使得這個委託的具體執行方式變成了詩人的Persuade方法——勸服強盜
poet.eliminate(Bob);//詩人對Bob執行了自己的委託實例eliminate
Console.ReadLine();
}
}
}
---------------------------------------
執行結果:
---------------------------------------
3.歸納總結
通過上面的大型示例,你現在是否已經初步瞭解了委託-delegate的作用呢?
委託是一個類,它通過描述一組【參數類型和順序】,定義了方法的類型,從而使得:若干個不同的方法,只要具備相同的【參數類型和順序】,就可以被歸納爲同一類型,也就是"委託"。
(1)通過將方法聲明爲委託的實例(例如上文中的eliminate),我們可以將具體的方法賦值給該委託實例,從而動態地改變該委託實例所代表的具體方法內容,增加程序的靈活性;
(在示例中,戰士和詩人按照各自的理解,對委託實例Eliminate eliminate作出了不同的執行方式,就是靈活性的體現)
(2)而通過將委託作爲方法的形參,我們還可以將一個【符合委託所需參數格式】的方法當作【另一個方法的參數】來進行傳遞。這種將方法動態地賦給參數的做法,可以避免在程序中大量使用If-Else(Switch)語句,同時使得程序具有更好的可擴展性。
注意:出於絕對淺顯易懂的需要,上面的內容犧牲了很多嚴謹性和全面性,並沒有全面地介紹委託的性質和用法,你可以自行查閱其它資料來完善你學到的知識。
到這裏,你有可能會覺得,委託的概念有點“花裏胡哨”,實際的作用不是很明顯;這樣想其實是有道理的,因爲我們還沒有見識到委託的主要作用在何處。
其實,委託是C#中事件驅動機制的基礎;【事件】纔是委託最大的用武之處。
那麼,事件驅動又是什麼呢?我們下篇筆記再會~