C#3.0筆記(一)預備知識之Delegate

作者: Henllyee Cui  來源: 博客園  發布時間: 2009-04-09 15:38  閱讀: 1634 次  推薦: 0   原文鏈接   [收藏]  
摘要:在學習C#3.0之前還是先來回顧下委托、事件,因為這樣能更加有助于理解C#3.0里面的一些新的特性,如Lambada表達式等。

  在學習C#3.0之前還是先來回顧下委托、事件,因為這樣能更加有助于理解C#3.0里面的一些新的特性,如Lambada表達式等。

  背景

  在C語言中我們可以用函數指針來創建回調函數,但是在C里面回調函數存在一些安全問題。因為它只是在內存地址中記錄了下來,并沒有像方法的參數類型、參數個數、返回值等其他安全信息。而在.Net FrameWork中,回調仍然是可以的,.net framework中提供了更為高級的更為安全的面向對象的delegate來實現。

  定義委托

  在委托中主要包含了三個重要的信息:

  1.調用的方法的名稱;

  2.方法的參數;

  3.方法的返回值。

  定義一個簡單的委托:

    public delegate int Caculate(int x,int y)

  這樣的委托就是簽名了參數為兩個int類型返回值為int類型的參數,Caculate類型的對象可以在運行時動態地調用其指向的方法。要注意的是.net委托既可以指向動態的方法也可以指向靜態的方法。

  C#編譯器在處理delegate的時候,它會先自動產生一個繼承于System.MulticastDelegate的類。正是這樣的類根System.Delegate為委托提供了必要的基礎信息,以便來維護需要調用的方法列表。我們可以通過IL查看器看到:

image

  生成的Caculate類中定義了三個方法:BeginInvoke、EndInvoke、Invoke。其中Invoke是核心的方法,它用來以同步的方式調用委托列表中的每個方法。我們可以看一看編譯器是如何定義這幾個方法的。Invoke方法中的參數跟返回值完全跟Caculate委托的定義一樣的,而BeginInvoke中多了兩個參數一個是AsyncCallback類型的一個是object類型的,EndInvoke方法返回Int類型。

  通過MulticastDeletate跟Delegate基類獲取更多信息

  我通過上面的IL代碼也可以看到編譯器生成委托時的類是繼承于MulticastDelegate的,而MulticastDelegate繼承于Delegate類,所以可以通過這兩個類來獲取委托更多的輔助信息。在這里只列出一些常用的屬性和方法,可以在msdn上獲取更多地這兩個類的內容(MulticastDelegate成員)。

  1.Methos屬性:返回System.Reflection.MethodInfo類型,描述委托所表示的方法信息。

  2.Target屬性:返回委托方法所在的對象,如果是靜態方法即返回null。

  3.GetInvocationList方法:返回一個Delegate類型的數組,其中數組的每個元素表示一個可以調用的方法。

  4.Combine方法: 靜態方法用來給委托添加一個方法。

  5.Remove方法:靜態方法給委托移除某個方法。

  看下簡單的Caculate的實現,CaculateClient類:

 
 public class CaculateClient
    {
        public int Add(int x, int y)
        {
            return x + y;
        }

        public int Subtract(int x, int y)
        {
            return x - y;
        }
    }

  另外定義了一個輔助方法:

public static void DisplayDelegateInfo(Delegate del)
{
    foreach (Delegate d in del.GetInvocationList())
    {
       Console.WriteLine("Method Name:{0}", d.Method.Name);
       Console.WriteLine("Target is:{0}", d.Target);
     }
}

 

  調用:

static void Main(string[] args)
{
       CaculateClient caClient =new CaculateClient();
       Simple.Caculate ca = new Simple.Caculate(caClient.Add);
       Console.WriteLine("1+1={0}",ca(1,1));
       ca += new Simple.Caculate(caClient.Subtract);
       Console.WriteLine("Result:{0}", ca(1, 1));
       Simple.DisplayDelegateInfo(ca);
       Console.Read();
}

 

  我們可以看到下面的結果:

image

小結

現在我們基本上知道Delegate的原理,已經基本的實現,但是我們并沒有實現一些高級的話題,畢竟Caculate還只是一個玩具,呵呵。下一篇中將會涉及到多播、復雜點的示例以及事件

0
0
 
標簽:CSharp
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()