學習委托那段時間是我對編程最頭疼的幾個時間段之一,.net中的委托自從出現以來,就開始了它征服程序員和被程序員征服的歷程。直到現在,我依然不敢說自己對委托的認識已經足夠清晰,也許它並不很難,可是我覺得它很繞。今天說說委托的前世今生,不知道對學習委托的人有沒有用。
委托前世:與指針的各種糾葛
如果說委托是憑空發明的,似乎有點說不過去,因為指針不同意,有些指針認為委托繼承了它的一些基因。
都知道C語言中有一種很強大的武器就是指針,指針一個比較大的用處就是允許我們手動操作內存,這一點也是與現今的托管代碼高級語言的一個主要區別。變量的內存地址可以存儲在相應的指針變量中,同樣函數的首地址也可以存儲在某個函數指針變量里的。這樣我們就可以通過這個函數指針變量來調用其所指向的函數了。
一般情況下很少會直接將函數指針作為函數參數傳遞,但如果想在一個方法里調用用戶傳遞的函數並通知用戶我們進行了某項操作,繼而讓用戶繼續他的使用或操作。具體代碼可以自己查閱相關的資料,我就不給出了,大學考過C語言以后沒怎么寫過,我腦中的C已經生銹了。
委托的今生:面向對象時代肩負重任
在我看來(當然也是學習別人的見解),所謂委托就是在面向開發對象領域中,對傳遞函數作為參數的實現方式,它記錄了方法所依附的對象及方法的相關信息。
隨着面向對象時代的到來,新的開發方法和模式逐漸的取代了面向過程的開發。對象作為面向對象中開發的基本單位,是數據和操作的組合體,封裝了數據和操作。這樣的話,很顯然我們不能將函數直接作為參數傳遞了。作為一種新生代的語言,C#除了引入一些新的特性之外,同時也需要兼容一些已經存在的技術。
我們都知道既然方法都依附於某個對象,那么我們就可以定義一個類,來記錄方法的相關信息,這樣不僅保證了方法的唯一性,同時也提高了代碼的安全性。所以在C#中引入了委托,委托是一種定義方法簽名的類型。當實例化委托時,可以將其實例與任何具有兼容簽名的方法相關聯。我們可以通過委托實例調用方法。委托用於將方法作為參數傳遞給其他方法。事件處理程序就是通過委托調用的方法。您可以創建一個自定義方法,當發生特定事件時某個類就可以調用我們的方法。
簡單講解一下對委任的理解
我看過至少十個委托的講解版本,每個都有自己的使用習慣,當時覺得委托變化太多端(這可能也是最開始把我弄懵的原因之一吧),現在我簡單用代碼為初學者解釋一下委托吧:
public abstract class Delegate : ICloneable, ISerializable { // 摘要: // 初始化一個委托,該委托對指定的類實例調用指定的實例方法。 // // 參數: // target: // 類實例,委托對其調用 method。 // // method: // 委托表示的實例方法的名稱。 // // 異常: // System.ArgumentNullException: // target 為 null。 - 或 - method 為 null。 // // System.ArgumentException: // 綁定到目標方法時出錯。 protected Delegate(object target, string method); // // 摘要: // 初始化一個委托,該委托從指定的類調用指定的靜態方法。 // // 參數: // target: // System.Type,它表示定義 method 的類。 // // method: // 委托表示的靜態方法的名稱。 // // 異常: // System.ArgumentNullException: // target 為 null。 - 或 - method 為 null。 // // System.ArgumentException: // target 不是 RuntimeType。請參見反射中的運行庫類型。 - 或 - target 表示開放式泛型類型。 protected Delegate(Type target, string method); }
一句話說明我對委托的使用感受
在用過了這么多年委托之后,有種特別強烈的感覺:如果C#中沒有了委托,它還能做什么?(個人觀點,可能有點小偏激,大家不要噴)。