c#中的委託可以理解一種類,這種類例項化後可以將函式的包裝成乙個變數(該變數就變成了對該函式的「引用」),它使得這個變數(函式)可以作為引數來被傳遞,這在作用上相當於c中的函式指標。c用函式指標獲取函式的入口位址,然後通過這個指標來實現對函式的操作。
委託的定義和方法的定義類似,只是在定義的前面多了乙個delegate關鍵字。如下定義:
public delegate void mydelegate(int para1, string para2);
委託能包裝的方法是有一定限制的,例如能被前面的委託型別mydelegate包裝的方法需要滿足以下條件:
1.方法的返回型別必須為void;
2.方法必須有兩個引數,並且第乙個引數應為int型別,第二個引數為string型別。
總結:可以被委託包裝的方法必須滿足以下規則:
1.方法的簽名必須與委託一致,方法簽名包括引數的個數、型別和順序;
2.方法的返回型別要和委託一致,注意,方法的返回型別不屬於方法簽名的一部分。
//委託使用的演示
class program
void add(int para1, int para2)
private static void mymethod(mydelegate mydelegate)
}
從以上**可以看出,使用委託的步驟為:定義委託型別—宣告委託變數—例項化委託—將例項作為引數傳遞給另乙個方法—該方法呼叫委託。如下具體分析委託的使用過程。
(1)定義委託型別: public delegate void mydelegate(int a, int b);。其定義方式類似於方法的定義,只是多了乙個delegate關鍵字。
(2)宣告委託變數:mydelegate d;既然委託是一種型別,那麼可以使用委託來宣告乙個委託變數,相當於int a;
(3)例項化委託: d = new mydelegate(new program().add);。第二步只是宣告了委託變數,但並沒有將它例項化。類的例項化使用new關鍵字來實現,而委託也屬於一種「類」,所以委託的例項化也使用new關鍵字來進行的。這裡需要注意的是,委託的例項化是用乙個方法名(不能帶左右括號)作為引數,並且該方法的定義必須符合委託的定義,即該方法的返回型別、引數個數和型別必須與委託定義中的一樣。這樣,前面3步就好比構造了乙個律師物件,而方法instancemethod好比是當事人的方法。
(4)作為引數傳遞給方法:mymethod(d);。委託使用得在c#中,可以把乙個方法作為另乙個方法的引數,而委託可以看作是乙個包裝方法的物件。
(5)在方法中呼叫委託。mymethod(d);。委託使用得在c#中,可以把乙個方法作為另乙個方法的引數,而委託可以看作是乙個包裝方法的物件。
總結:在使用委託時,需要注意以下幾個問題。
1.在第三步中,被傳遞的方法的定義必須與委託定義相同,即方法的返回型別和引數個數、引數型別都必須與委託相同。並且,傳遞的是方法名,方法名後不能帶有左右括號。
2.在第五步中,委託的呼叫與方法呼叫類似,傳遞的實參型別和個數必須與委託定義一致。
3.由於委託是方法的包裝型別,所以對委託的呼叫也就是對其所包裝的的方法的呼叫,上面第5步時間上是呼叫了add方法來對傳入的實參進行計算。
委託鏈其實就是委託型別,只是委託鏈把多個委託鏈結在一起而已,也就是說,我們把鏈結了多個方法的委託稱為委託鏈或多路廣播委託。如下:
public delegate void delegatetest();
static void main(string args)
private static void method1()
private void method2()
從委託鏈中移除委託
//使用 「+」符號鏈結委託,鏈結多個委託後就成為了委託鏈
delegatechain += dtstatic;
delegatechain += dtinstance;
//使用 「-」運算子 移除委託
delegatechain -= dtstatic;
上一章中我們可能會很疑惑,為什麼需要委託?為什麼不直接在mymethod方法裡直接呼叫add方法,反而要例項化乙個委託物件來完成呼叫呢?這豈不是自找麻煩嗎?
當然,c#引入委託並不是自找麻煩。委託是c#最好的乙個特性,它為後來的很多特性都打下了基礎。委託使得乙個方法可以作為另乙個方法的引數進行傳遞,這就是委託最大的作用。如下例子:
例如我們要實現乙個打招呼的方法,而每個國家打招呼的方式都不一樣,剛開始我們可能會像下面這樣實現打招呼的方法:
public void greeting(string name, string language)
}public void englishgreeting(string name)
public void chinesegreeting(string name)
若後續我們需要新增德國、日本等打招呼方法,就必須修改greeting方法內的case語句,來適應新的需求,這樣特別不方便。有了委託,我們就可以把函式作為引數,並像如下**實現greeting方法:
public delegate void greetingdelegate(string name);
static void main(string args)
public void greeting(string name, greetingdelegate callback)
public void englishgreeting(string name)
public void chinesegreeting(string name)
class program
}public class bookstore
}public class reader
}
執行結果:
示例2
class program
}public class bookstore
public delegate void publish_english(string bookname); //宣告自己的委託
public event publish_english on_publish_english; //宣告委託註冊的事件
//發行電腦的觸發方法
public void issue_english()
}public class reader
// 定義收到雜誌的方法
public void received_book(string bookname)
}
執行結果:
示例3
class program
}
// 發布事件類
public class pubeventargs : eventargs
}public class bookstore
// 委託有些類似於類的靜態方法, 可以通過bookstore.pubcomputereventhandler進行訪問
// 委託實際上是一種類,可以使用new關鍵字例項化
// 例項化後,就是對函式包裝(引用),使得函式可以作為引數傳遞或賦值。
public delegate void pubcomputereventhandler(object sender, pubeventargs e); //宣告電腦的委託
public event pubcomputereventhandler pubcomputer; //宣告委託註冊的事件
//發行電腦的觸發方法
public void issuecomputer(string bookname, datetime booktime)
public delegate void pubenglisheventhandler(object sender, pubeventargs e); //宣告自己的委託
public event pubenglisheventhandler pubenglish; //宣告委託註冊的事件
//發行電腦的觸發方法
public void issueenglish(string bookname, datetime booktime)
}public class reader
// 定義收到雜誌的方法,引數不是乙個簡單的變數而是pubeventargs例項
public void received_book(object sender, pubeventargs e)
}
允行結果:
C 「委託」學習筆記
using system using system.collections.generic using system.linq using system.text namespace delegatetest console.writeline sh3 jiang 組合委託,此時委託就能夠依次執行多...
C 學習筆記 委託
什麼是委託?委託 delegate 是一種可以把引用儲存為函式的型別。委託的宣告非常類似於函式,但不帶函式體 且要使用 delegate關鍵字。委託的宣告指定了乙個型別和引數列表。在定義了乙個委託後就可以宣告該委託型別的變數。接著把這個變數初始化為與委託有相同返回型別和引數列表的函式引用。之後,就可...
C 委託學習筆記
namespace delegate private static void chinesegreeting string name 注意此方法,它接受乙個greetingdelegate型別的方法作為引數 private static void greetpeople string name,gr...