還是關於“委託”

以下是從網上找來的資料:

1.委託概述

委託是C#中新加入的一個類型,可以把它想作一個和Class類似的一種類型,和使用類相似,使用一個委託時,需要兩個步驟,首先你要定義一個委託,就像是定義一個類一樣;然後,你可以創建一個或多個該委託的實例。

定義一個委託的語法是這樣的:

[public/protected/private]delegate returnType delegateName(paramtype param1,…)

這是我自己寫的,看起來好像有點怪怪的,我來解釋一下,private/protected/private是限定詞,就不多說了,delegate是申明一個委託的關鍵詞,returnType是一個返回類型,delegateName是一個你給委託起的名字,你可以寫任何一個你喜歡的名字,paramtype param1…這個是參數列表。說了這麼多可能看起來還是不是很好理解,我是這樣認爲的,實用點來講,委託定義就是在一個函數定義中間加入一個delegate的關鍵詞。它的作用類似於你申明一個類:

public class ClassName {…}

創建一個委託的實例:

[public/protected/private]delegateName deleInstanceName = new delegateName(MethodName)

這個類似於實例化一個類,public ClassName instancename = new ClassName(…),這裏有個要注意的地方,即MethodName方法要和delegateName的簽名一致。什麼是簽名一致,就是說MethodName的參數列表,返回值要分別和returnType、(paramtype param1,…)一致。舉個例子來說明下:

publicdelegate string DelegateDemo(string name, int age);

比如我們如上定義了一個委託,就寫法來說,其實就是在函數 string DelegateDemo(string name, int age)前面加了一個delegate的關鍵字,下面我們來用創建一個函數:

public string AgentDemo(string name, intage)

{

string rev = “”;

    return rev;

}

這個函數是做參數傳遞給一個DelegateDemo實例的,接下來創建一個DelegateDemo的實例:

DelegateNameinstanceDemo = new DelegateName(AgentDemo);

這時要說到一致了,即AgentDemo和聲明委託時的DelegateDemo(我們姑且將delegate去掉)這兩個函數的返回值,參數列表要相同。終於說完了,不知道看的人明不明白。

接下來,我們可以使用這個委託了(調用一個委託),如下:

string name = “cshape”;

int age = 20;

instanceDemo(name, age);

當instanceDemo執行時,會執行AgentDemo函數,instanceDemo相當於C裏的一個函數指針,現在這個指針指向AgentDemo的函數入口地址。

 

2.多點委託

前面提到的委託都只包含對一個方法的調用,如果需要調用多個方法,需要多次顯示的調用這個委託,我們還有另的選擇,我們可以讓一個委託中包含多個方法,這樣我們一次顯示調用委託,就可以按照順序連續的調用多個方法。看下面的例子:

public delegate void MultiDelegate(stringname);

public void AgentDemo1(string str)

{

    Console.WriteLine(str + “this is AgentDemo1\n”);

}

 

public void AgentDemo2(string s)

{

     Console.WriteLine(s + “this isAgentDemo2\n”);

}

 

MultiDelegate multiDemo = newMultiDelegate(AgentDemo1);

multiDemo += new MultiDelegate(AgentDemo2);

multiDemo(“multiDemo test :”);

 

輸出的結果應該是:

multiDemo test :this is AgentDemo1

mutliDemo test :this is AgentDemo2

 

可以看到我們一次顯示的調用一個委託,它順序的(按照你添加方法的順序)執行了方法AgentDemo1和AgentDemo2。這裏要注意的有幾點:

●     委託支持 +=,-=這樣的運算符,對應爲添加或去掉一個方法

●     多點委託不可以定義有返回值,因爲無法處理多個方法的返回值,所以如果要使用多點委託,應該用void,否則你的編譯會返回一個錯誤

●     多點委託不建議你的參數列表中有OUT的類型,這樣只會out最後一個方法的值,其他的值會丟失。

 

3.委託的理解

首先申明,這只是我舉的一個例子,目的是幫助理解委託的過程,其中很多地方都經不起推敲,望大家知悉。言歸正傳,

你想要吃飯,

但是自己又不會做(委託方不知道實現細節),

你計劃找個飯店,叫個回鍋肉飯(定義了一個委託)

你決定找常去的那家叫做A的飯店(實例化一個委託)

你打電話給A飯店(委託調用)

A飯店給你做好了你的回鍋肉飯(代理函數工作)

飯來了,真好。

 

4.委託的使用時機

當你需要把一個方法傳送給其他方法時,可以考慮使用委託。好像不是很好理解,也可以這樣說,當你確定要處理一件事,但又不能確定處理方法時,可以考慮用委託。其實單獨的說委託的應用好像有點牽強,委託更多的是在事件中的應用。

 

5.一個委託的例子

我用兩個類來做這個例子,一個類,我稱它爲委託方,一個類我稱它爲代理方,代碼如下:

using System;

namespace Visen.Demo.Delegate

{

    ///<summary>

    /// StartUp 委託演示中的程序入口,含委託方。

    ///</summary>

    class StartUp

    {

    #region公用的方法

        #region應用程序的主入口點。

        ///<summary>

        ///應用程序的主入口點。

        ///</summary>

        [STAThread]

        static void Main(string[] args)

        {

              Console.WriteLine("This is adelegate demo\n");

              Visen.Demo.Delegate.Agent ag =new Agent();

              //定義一個委託類型的對象

              OutMessage singleDele = newOutMessage(ag.ShowMessage);

              OutMessage deleStaticMeth = newOutMessage(Agent.SShowMessage);

              //定義一個多點委託

              OutMessage MultiDele = newOutMessage(ag.ShowMessage);

              MultiDele += newOutMessage(Agent.SShowMessage);

              singleDele(" delegateinstance singleDele");

              deleStaticMeth(" delegateinstance deleStaticMeth");

              MultiDele(" this is aMultiDele");

              Console.Read();

        }

        #endregion應用程序的主入口點。

    #endregion公用的方法

    #region私用的字段

        ///<summary>

        ///定義一個委託類型

        ///</summary>

        private delegate void OutMessage(string msg);

    #endregion私有的字段

    }

}

 

下面是代理方:

using System;

namespace Visen.Demo.Delegate

{

    ///<summary>

    /// Agent 類爲委託者的代理方,處理委託者委託的事務。

    ///</summary>

    public class Agent

    {

    #region公用的方法

        #region空的構造函數

        ///<summary>

        ///空的構造函數

        ///</summary>

        public Agent()

        {

        }

        #endregion空的構造函數

        #region顯示一條信息到控制檯,一個類成員函數作爲代理方

        ///<summary>

        ///顯示一條信息到控制檯,一個類成員函數作爲代理方

        ///</summary>

        ///<param name="msg">顯示內容</param>

        public void ShowMessage(string msg)

        {

              Console.WriteLine("MethodShowMessage out:" + msg + "\n");

        }

        #endregion顯示一條信息到控制檯,一個類成員函數作爲代理方

        #region顯示一條信息到控制檯,一個類靜態函數作爲代理方

        ///<summary>

        ///顯示一條信息到控制檯,一個類靜態函數作爲代理方

        ///</summary>

        ///<param name="msg">顯示信息</param>

        public static void SShowMessage(string msg)

        {

              Console.WriteLine("staticMethod SShowMessage out:" + msg + "\n");

        }

        #endregion顯示一條信息到控制檯,一個類靜態函數作爲代理方

    #endregion公用的方法

    }

}

輸出爲:

This is a delegate demo

Method ShowMessage out: delegate instancesingleDele

static Method SShowMessage out: delegateinstance deleStaticMeth

Method ShowMessage out: this is a MultiDele

static Method SShowMessage out: this is aMultiDele

 

可見:方法函數可以是類成員函數,也可以是一個靜態成員,只要和委託的簽名相同就可以了。

 

有錯的地方,請大家批評指正,謝謝!

發佈了34 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章