委託學習筆記1:委託的基本使用

1、引子ide

在正式說委託前,我先給一個例子,而後引出後面要說的委託。spa

很簡單,就是一個機器人打招呼的。code

代碼清單1.1對象

    class Robot
    {
        public void GreetByChinese(string name)
        {
            Console.WriteLine("你好," + name + "!");
        }
        public void GreetByEnglish(string name)
        {
            Console.WriteLine("Hello," + name + "!");
        }
        //打招呼
        public void DoGreet(string name,string lang)
        {
            switch (lang)
            {
                case "chinese":
                    GreetByChinese(name);
                    break;
                case "english":
                    GreetByEnglish(name);
                    break;
                default: break;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //實例化機器人對象
            Robot robot = new Robot();
            string name = Console.ReadLine();
            robot.DoGreet(name,"chinese");
            robot.DoGreet(name,"english");
            Console.Read();
        }
        
    }
View Code

代碼清單1.1中建立了一個機器人類,類中封裝了兩個打招呼的方法和一個調用這兩個方法的公共方法。DoGreet方法中,只要帶nameswitch中的條件,就能夠打印出對應語言打招呼的語句。blog

那麼,若是我要增長其餘的語言,如法語、日語、韓語等,我除了增長對應的方法,還須要改DoGreet方法裏的case語句,維護量較大。那有什麼辦法能夠解決這種尷尬呢?string

一種比較簡單的方法是,直接將方法做爲參數(變量),傳給另外一個方法(DoGreet),在其中執行便可。it

但咱們都知道,能做爲方法的參數的是某一類型的對象或變量,而方法是個什麼類型呢?確實找不出方法對應的類型。但依然有種方法能夠間接的將方法做爲一個參數來使用,這便引出了,下面要提到的「委託」。 event

2、關於委託,微軟給出的定義以下:class

「委託用於將方法做爲參數傳遞給其餘方法。」變量

早在C#1.0時,就已開始支持這個特性(用過VS2003的園友,應該是最清楚不過了)。關於微軟給出的定義,已經很好理解了:咱們利用委託,把方法做爲一個參數(變量)傳遞給其餘的方法,從而由其餘方法來代爲執行這個當作參數的方法裏的動做。 

3、那麼怎麼去使用委託呢?

使用委託,基本要按照以下步驟實現:

一、定義一個委託類型

訪問修飾符 delegate 返回類型 委託類型名稱(參數列表);

Expublic delegate void Greet(string name);

二、建立一個執行某動做的方法(返回類型和參數列表須與委託類型相同)

訪問修飾符 返回類型 方法名稱(參數列表){......}

Expublic void GreetByChinese(string name)

{

Console.WriteLine(「你好,」+name+「!」);

}

三、實例化委託類型

委託類型名稱 委託對象名稱=方法名稱;

ExGreet greet=GreetByChinese;

四、開始使用,執行操做

委託對象名稱(參數列表);

或:委託對象名稱.Invoke(參數列表);

Exgreet(「季節旋風」);  或:greet.Invoke(「季節旋風」); 

如上,就這麼個簡單的流程,是否是很簡單。但這裏,可能有人會說,定義中不是將方法做爲參數傳給另外一個方法嗎?怎麼沒有這麼用?其實這個不用擔憂,咱們已經在步驟3中將方法引用給了greet對象,既然是對象,那麼久能夠做爲方法的參數,就能夠很好地解決這個疑問。

具體的看下面的代碼清單3.1

 

    //一個經常使用的委託,打招呼
    delegate void Greet(string name);
    //一個機器人類,封裝打招呼
    class Robot
    {
        public void GreetByChiness(string name)
        {
            Console.WriteLine("你好," + name + "!");
        }
        public void GreetByEnglish(string name)
        {
            Console.WriteLine("Hello," + name + "!");
        }
public void GreetByJapaness(string name)
{
Console.WriteLine("こんにちは," + name + "!");
}
        //打招呼
        public void DoGreet(string name, Greet greet)
        {
            greet(name);
        }
    }
    class SampleDelegate
    {
        static void Main(string[] args)
        {
            //實例化機器人對象
            Robot robot = new Robot();
            string name = Console.ReadLine();
            //經過把方法做爲變量來實現打招呼
            robot.DoGreet(name, robot.GreetByChiness);
            robot.DoGreet(name, robot.GreetByEnglish);
robot.DoGreet(name, robot.GreetByJapaness);
            Console.Read();
        }
}
View Code

 

執行結果以下:

 

依然是機器人大招呼的例子,但用到了委託,這樣一來是否是更簡潔了?這裏已經能夠輕鬆地將方法做爲參數傳遞給執行方法(DoGreet)中,並在其中執行操做。 

4、合併委託(多路廣播委託)

委託對象的一個有用屬性是:可使用 「+」 運算符將多個對象分配給一個委託實例。 多播委託包含已分配委託的列表。 在調用多播委託時,它會按順序調用列表中的委託。 只能合併相同類型的委託。 「-」 運算符可用於從多播委託中移除組件委託。

依然用機器人打招呼的例子來說,這裏就再也不使用DoGreet方法了,直接在Main方法中來作「打招呼」動做。以下(代碼清單4.1):

 

Greet greet = robot.GreetByChiness;
greet += robot.GreetByEnglish;
greet += robot.GreetByJapaness;
greet(name);

 

在運行時,它會按順序執行調用的方法,以下圖:

值得注意的是,只有對委託對象greet初始化後纔可進行多播操做,例以下面的這種寫法就是錯誤的:

Greet greet+= robot.GreetByChiness;

在執行移除(「-」)操做時,跟合併操做相似,但它是從委託中移除已有的方法。例如將代碼清單4.1的代碼後面加上,下面代碼(代碼清單4.2):

 

Console.WriteLine("移除日語後:");
greet -= robot.GreetByJapaness;
greet(name);

 

那麼第二次greet時,會少一個日語問候,執行結果以下圖:

相關文章
相關標籤/搜索