前言: 在我們學習C#的過程中,我們會學習到C#委托和事件,由於這是C#中比較高級的內容,所以學起來相當的費力,沒有一定的時間是體驗不來的,正好我這幾天在學這個知識點,所以做一個小總結,希望和我一樣的童鞋們能夠參考一下,我們共同進步!,此博客屬於學習筆記,寫的不好,還請見諒!
1. 委托的定義
(1) 將方法作為變量使用的一種機制,就是將方法當作變量用(聲明,賦值,傳參)
(2) 將變量當作方法來用,首先就要去聲明變量,就要考慮變量的類型,就是(委托變量,對應方法的返回值,參數等),顧名思義:委托就是委托別人去干某些事情,下面是一個實例方法的實現
例如:我現在餓了,但是我很懶,就是不想出去買,所以這時候我可以委托室友幫我帶一份,這樣我就已經實現委托了,
如果我想去吃飯的話實現的代碼是:
class Program { static void Main(string[] args) { chum ch = new chum(); ch.EatFood(); Console.ReadKey(); } } class chum { public void EatFood() { Console.WriteLine("我要去吃飯了!"); } }
但是我今天很懶,我要在宿舍睡覺,所以我委托別人帶,這樣實現代碼就是
//定義委托
public delegate void EatFootDelegate(); class Program { static void Main(string[] args) { chum ch = new chum(); //這個地方就是授權,因為委托已經定義了這個委托類型可以使用什么方法 //直接為變量賦值就可以了,賦值的時候使用方法名(不要括號) EatFootDelegate leadfood = ch.EatFood; //此時我的室友就等同於我買吃的東西的方法了 leadfood(); Console.ReadKey(); } } class chum { public void EatFood() { Console.WriteLine("我要去吃飯了!"); } }
最后將這幾點做個總結如下:
(1)使用委托,就是需要有一個變量來指向這個方法
(2)定義一個委托類型的變量,先要定義一個委托(這個委托規定了可以賦值方法的信息)
(3)語法:delegate 方法返回類型 委托類型名(方法可用參數)
(4)委托就是一個類型
(5)使用委托就是讓方法可以當成變量用
1) 弄清楚那些方法需要當作變量用
2) 根據方法的返回值和類型定義委托類型
3) 聲明委托類型的變量
4) 初始化委托變量(就是賦值)
5) 此時這個委托變量就是等價於方法了,使用委托變量加圓括號就是在調用指定的那個方法
6) 既然是變量,就可以通過參數傳遞等其他方式使用了
2. 靜態方法實現委托
(1)委托變量在指向方法的時候,就是"相當於"存放着方法的地址,在調用的時候直接到內存中找到方法代碼,執行
(2) 既然委托只是存儲方法,就不需要理會這個方法是什么類型的(靜態還是實例的)
(3)實現調用方法的時候就是直接為其賦值即可
public delegate void FuncDelegate(); class Program { static void Main(string[] args) { FuncDelegate func = SayHello; func(); Console.ReadKey(); } static void SayHello() { Console.WriteLine("我是一個靜態方法"); } }
(4)如果沒有為委托變量賦值,那么會拋出異常(因為委托變量是null)
FuncDelegate func = null;
func();
這樣但在執行的時候會拋出異常"未將對象引用到對象的實例"
(5)委托是具有面向對象特征的,所以你也可以new出對象
public delegate void FuncDelegate(); class Program { static void Main(string[] args) { FuncDelegate func = new FuncDelegate(SayHello); func(); Console.ReadKey(); } static void SayHello() { Console.WriteLine("我是一個靜態方法"); } }
(6)委托在使用的時候,由於委托變量指的就是方法,所以一般給委托變量命名使用Pascal命名規則
(7)委托是一個類(與指針的區別)
(8)自己定義的委托來自於MulticastDalagete類型,而Multicastdatagete有來自於Delegate類型
3. Invoke
(1)委托變量作為方法進行進行調用執行,其本質就是Ivoke方法實現的
FuncDelegate func=Function;
func()等價於 func.Invoke(),下面代碼說明了這點
public delegate void FuncDelegate(); class Program { static void Main(string[] args) { FuncDelegate func = Show; func.Invoke(); Console.ReadKey(); } public static void Show() { Console.WriteLine("Invoke"); } }
4. 實例方法和靜態方法在執行時的一點小區別
(1)因為實例方法包含實例的成員,所以執行的時候我們設置斷點可以查看一下這個簡單的方法的執行結果,代碼:
public delegate void FuncDelegate(); class Program { static void Main(string[] args) { Person p = new Person() { Name = "張三" }; FuncDelegate func = new FuncDelegate(p.sayHello); FuncDelegate funcstatic = new FuncDelegate(show); func(); funcstatic(); Console.ReadKey(); } public static void show() { Console.WriteLine("show"); } } class Person { public string Name { get; set; } public void sayHello() { Console.WriteLine(Name); } }
下面的章節還會詳細介紹委托和事件的