委托是一個類。
namespace ConsoleApplication1{internal delegate void MyDelegate(int val);class Program{static void Main(string[] args){}}}
使用Reflector查看委托的IL代碼:
○ 委托的確是一個類
○ 委托的構造函數接收方法和類實例
○ 而且是多播委托,可以用+=為委托變量賦值
○ 委托內部使用Invoke方法觸發方法
○ BeginInvoke和EndInvoke方法用於多線程場景
接下來體驗委托如何使用,以及委托的Method和Target屬性分別代表什麼。
namespace ConsoleApplication1{internal delegate void MyDelegate(int val);class Program{static void Main(string[] args){//委托與靜態方法MyDelegate d = new MyDelegate(M1);d(10);Console.WriteLine(d.Method);if (d.Target == null){Console.WriteLine("當前委托調用的是靜態方法,沒有類實例");}else{Console.WriteLine("當前委托調用的是實例方法,類實例為:" + d.Target);}Console.WriteLine("-------------------");//委托與實例方法Program p = new Program();d = p.M2;d.Invoke(10);Console.WriteLine(d.Method);if (d.Target == null){Console.WriteLine("當前委托調用的是靜態方法,沒有類實例");}else{Console.WriteLine("當前委托調用的是實例方法,類實例為:" + d.Target);}}static void M1(int val){Console.WriteLine("我是靜態方法,輸出" + val);}void M2(int val){Console.WriteLine("我是實例方法,輸出" + val);}}}
○ 委托創建:通過委托構造函數,new MyDelegate(M1);也可通過d = p.M2,這是一種"語法糖"寫法,其內部也調用了委托構造函數。
○ 委托與靜態方法:只要兩者參數列表和返回類型一致,可把靜態方法傳給委托構造函數
○ 委托與實例方法:只要兩者參數列表和返回類型一致,可把實例方法傳給委托構造函數
○ 委托調用:像d.Invoke(10),通過委托的實例方法Invoke調用;像d(10),這是一種"語法糖"寫法,其內部也調用了實例方法Invoke。
○ Target屬性:委托所表示實例方法所屬的類實例名稱,如果是靜態方法,Target為null
○ Method屬性:委托所表示的方法,可能是靜態方法,也有可能是實例方法
“委托、Lambda表達式、事件系列”包括:
最大的作用是用在匿名函數和linq查詢上。
這是用在匿名方法上的:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
等價於
delegate int del(int i);
del myDelegate = delegate(int i){i=i*i;};
int j = myDelegate(5); //j = 25
至於linq前景不明,就不要深究了。
直接i+1???
呵呵,你是沒碰到一些必須用委托的情況。
比如跨線程調用,你只能用委托,而lambda表達式就是一個很方便的寫法。純粹為了方便而已。
委托定義如下:復制代碼 代碼如下:public class SocketSp{public delegate void ReceiveCompleted(byte[] receiveBuffer, int receiveTotalLen,Exception ex);public ReceiveCompleted receiveCompleted;}掛接方定義如下復制代碼 代碼如下:public class LinkOuter{SocketSp linkOuterSocket = new SocketSp();private void test(Socket requestHandleSocket){//此處要掛接 linkOuterSocket.receiveCompleted 事件,同時想將參數requestHandleSocket傳入,以便後續處理。}}第一個想法是利用delegate,但是失敗了。因為雖然掛接上去了,委托傳進的參數丟了,無法進行後續操作。復制代碼 代碼如下:private void test(Socket requestHandleSocket){linkOuterSocket.receiveCompleted += delegate {//To do};}第二個想法是利用Action,結果也失敗了。IDE提示委托Action未采用3個參數。復制代碼 代碼如下:private void test(Socket requestHandleSocket){linkOuterSocket.receiveCompleted += (Action)((outerReceiveBuffer, totalLen, ex) => {//To do});}第三個想法是利用lambda表達式,先與委托掛接,同時利用局部變量的調用,來實現參數傳遞到sendResponse函數中,以便後續操作。復制代碼 代碼如下:private void test(Socket requestHandleSocket){linkOuterSocket.receiveCompleted += new SocketSp.ReceiveCompleted((outerReceiveBuffer,totalLen,ex) =>{byte[] realOuterReceiveBuffer = new byte[totalLen];Array.Copy(outerReceiveBuffer, 0, realOuterReceiveBuffer, 0, totalLen);sendResponse(requestHandleSocket, realOuterReceiveBuffer,"200 OK", "text/html");});}最終用lambda表達式實現了。您可能感興趣的文章:C#用Lambda和委托實現模板方法