對於代表(委託也是它)delegate類型的意義,前面 引用類型前言 (點擊查看) 中已經介紹過了,這裡就不再羅嗦了,簡言之,委託是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞,說白了就是可以把方法當作參數傳遞。所有的委託(Delegate)都衍生自System.Delegate 類別。
(好像不太明白)打個比方吧,室友HC555 是個LOL愛好者,平時也喜歡逛淘寶買東西,當他正沉浸在LOL中的時候,快遞員打電話叫他去取快遞,打遊戲最煩的莫過於此了,於是就叫我代他將快遞取回來,此時我們將室友看作(roomfriend)類,取快遞是類裡面的一個方法(takepackage()),而我就是由Delegate實例化的一個物件(能夠攜帶方法的一個物件),「攜帶」 著室友中取快遞的這個方法。
委託的聲明:
所委託的聲明決定了該委託可引用的方法。委託可指向一個與其具有相同標籤的方法。
例如,聲明一個委託:
public delegate int MyDelegate(string str); //string类型的变量就是它的标签
上面的委託可被用於引用任何一個帶有一個單一的 string 參數的方法,並返回一個int 類型變數。
收到當建立委託時,將方法當變數一樣傳遞到 new 語句,但是方法不帶有參數。 例如:
public delegate int MyDelegate(string str); //委托的声明 ..... public static int Add(string s); //定义的一个方法 ..... MyDelegate my = new MyDelegate(Add) ; //实例化一个委托,其实就是实例化一个对象
代碼範例:
回到開始的取快遞故事中,我們將這個故事轉換成代碼:完快遞回寢室的時候,室友給我打來了一個電話,說他餓了,讓我路過超市的時候買點吃的,本著雷鋒精神,我答應了...在這裡"買東西" 也可看成是roomfriend中的一個方法,而「我「又」攜帶」了一個來自於他的方法 。在C#中用「+=」依序連接合併方法,呼叫時依序輸出;
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Test { public delegate void MyDelegate(string str); //委托的声明 class roomfriend //定义室友这个类 { public static void takepackage(string name) //定义一个取快递的方法 { Console.WriteLine("我叫 {0} 这是一个取快递方法",name); } } class program { static void Main(string[] args) { MyDelegate myd = new MyDelegate(roomfriend.takepackage); //实例化一个委托“我”携带一个方法(将方法当参数传入) myd("HC555"); //由我实现室友的方法,实际是室友的方法当参数传给了我 } } }
結果如下 :
(唉!我不是將快遞取了嗎?咋還有…0.0)
中我們用「+=」連接方法,當我們想要取消某個方法時自然可以用"-=" 解除與「我」的攜帶關係,因此在上面代碼中我們只需要加入 myd -= roomfriend.takepackage //放在+=下面 這樣就不會再呼叫取快遞這個方法了。
我從超市裡買了幾盒餅乾出來,手機又響了,又是室友,他告訴我,那包裹是買給他女朋友的,讓我給送過去下,好人做到底,我也答應他了。 。在給她女友快遞的時候,她有急事所以匆忙的將我所有的東西都拿走了,包括那幾盒餅乾。 。然後我笑了,愉快的回到寢室…這裡我們再定義一個(girlfriend)類,類別裡面有一個接收(accept)的方法,而我(委託)作為了方法的一個參數; 定義方法: public static void accept(string name,MyDelegate pack);如果將一個委託看作一個箱子,那麼這個箱子裡滿滿的都是具有相同類型參數的方法。我們將MyDelegate pack 與 string name 比較,name 是string類型的變量,pack可以說是MyDelegate類型的變數。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Test { public delegate void MyDelegate(string str); //委托的声明 class roomfriend //定义室友这个类 { public static void takepackage(string name) //定义一个取快递的方法 { Console.WriteLine("我叫 {0} 这是一个取快递方法",name); } public static void shopping(string name) //定义一个买东西的方法 { Console.WriteLine("我叫 {0} 这是一个买东西的方法",name); } } class program { static void Main(string[] args) { MyDelegate myd = new MyDelegate(roomfriend.takepackage); //实例化一个委托“我”携带一个方法(将方法当参数传入) myd += roomfriend.shopping; // += 合并运算顺序执行方法 myd("HC555"); } } }結果一樣
回思:
在上面我舉的例子中,是將「室友」或「室友的女朋友」看作一個類,我調用方法的時候使用的是類型名. 方法名,如果我用一個實例化的對象,透過物件名稱. 方法名稱 引用方法傳入委託 :
roomfriend myfriend = new roomfriend() ; //將室友實例化一個物件
努 //這裡會出錯,編譯器告訴我說無法透過實例引用訪問成員 為什麼用roomfriend的一個實例物件就會出錯了呢?原來在程式碼中儘管我將takepackage聲明為Public訪問,但實際上仍然會被編譯成私有字段,這就與我們在定義方法時用到的static 有關了(後面會細說的),如果去掉就可以這麼做了;以上就是 C#學習日記19----引用類型之委託(Delegate) 類型的內容,更多相關內容請關注PHP中文網(www.php.cn)!