程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 委托、Lambda表達式、事件系列01,委托是什麼,委托的基本用法,委托的Method和Target屬性,lambdatarget

委托、Lambda表達式、事件系列01,委托是什麼,委托的基本用法,委托的Method和Target屬性,lambdatarget

編輯:C#入門知識

委托、Lambda表達式、事件系列01,委托是什麼,委托的基本用法,委托的Method和Target屬性,lambdatarget


委托是一個類。

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表達式、事件系列”包括:

委托、Lambda表達式、事件系列01,委托是什麼,委托的基本用法,委托的Method和Target屬性

委托、Lambda表達式、事件系列02,什麼時候該用委托

委托、Lambda表達式、事件系列03,從委托到Lamda表達式


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表達式就是一個很方便的寫法。純粹為了方便而已。
 

C# 中怎利用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和委托實現模板方法
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved