1. 程式人生 > >c#之委托詳解

c#之委托詳解

添加 邏輯 定義 ole 函數 1.5 people 關鍵字 小夥伴

一、委托的概念

在我們學習委托之前,我們來了解下,什麽是委托呢?

官方概念:委托是一種安全地封裝方法的類型,它與 C 和 C++ 中的函數指針類似。與 C 中的函數指針不同,委托是面向對象的、類型安全的和保險的。委托的類型由委托的名稱定義。

很多初學者都看不懂官方的概念,一臉懵逼。

舉個例子吧:有幾個小夥伴在外面玩,突然有兩個人手機忘記帶了,並且兩個人家距離很近,其中一個人想要騎車回去拿,另一個不想回去,就委托另一個幫他拿。

其實委托就是一個類型,它所實例化的變量就是委托類型的變量,也可以說委托是一個方法的模板,當我們去掉delegate關鍵字的時候,就像是一個沒有方法體的方法。

二、委托聲明語法

delegate <return type> <delegate-name> <parameter list>

三、接下來我們來看下委托三部曲

    public class MyDelegate
    {
        ////1、委托的聲明
        public delegate void NoReturnNopara();
        public static void show() 
        {
            //2、委托的實例化
            NoReturnNopara method = new NoReturnNopara(Study);

            
//3、委托的調用 method.Invoke(); } public static void Study() { Console.WriteLine("正在學習delegate!"); } }

然後我們調用show方法來看一個結果:

技術分享圖片

結果沒毛病。

四、委托的用途

接下來我們來思考下,這樣用委托有什麽意義呢?還不如直接 MyDelegate.Study(); 這樣。

當然我們學習委托並不是簡單的像上面一樣,上面只是為了便於我們學習了解委托而已。接下來我們來看一個打招呼的例子:

public class MyGreeting
    {
        public static void GreetingChinese(string name) 
        {
            Console.WriteLine("{0},早上好",name);
        }
        public static void GreetingEnglish(string name)
        {
            Console.WriteLine("{0},good morning",name);
        }
    }

上面是中國人和外國人打招呼的方式,那個問題來了,我們怎麽確定打招呼的人是中國人還中外國人呢?簡單,我們定義一個枚舉然後判斷一個不就ok了嘛。

    public class MyGreeting
    {public static void Greeting(string name,PeopleType type) 
        {
            switch (type)
            {
                case PeopleType.Chinese: Console.WriteLine("{0},早上好", name);
                    break;
                case PeopleType.English: Console.WriteLine("{0},good morning", name);
                    break;
            }
        }
    }
    public enum PeopleType
    {
        Chinese,
        English
    }

這種做法滿足了我們的需求。但是我們應該有所發現,這個方法的可擴展性很差,日後我們要是又有一個需求,要添加日本人打招呼,韓國人打招呼怎麽辦?我們就不得不修改枚舉和Greeting這個方法內的代碼,真是糟糕逶了。

那麽,我們就應該想其它的方法來解決這個問題。從而達到”對擴展開方,對修改封閉“的原則。怎麽實現呢?我們可以不管是哪國人,只負責打招呼就好,將打招呼的邏輯做為參數。

首先,我們先定義一個打招呼的委托。

 public delegate void DeleGreeting(string name);

然後將這個委托做為參數傳給 Greeting(string name,DeleGreeting greeting) 這個方法,讓這個方法來調用打招呼。

        public static void Greeting(string name,DeleGreeting greeting) 
        {
            greeting.Invoke(name);
        }

最後,我們來實例化這個委托,並調用這個方法。

        static void Main(string[] args)
        {
            DeleGreeting method = new DeleGreeting(MyGreeting.GreetingChinese);
            MyGreeting.Greeting("張三",method);

            DeleGreeting method1 = new DeleGreeting(MyGreeting.GreetingEnglish);
            MyGreeting.Greeting("lucy", method1);

            Console.Read();
        }

結果如下:

技術分享圖片

用這種方式實現的話,以後不管你添加多少種國家的打招呼。都不用去改動 Greeting(); 這個方法,只需要擴展一個打招呼的方法就行了。達到”對擴展開方,對修改封閉“的原則。

五、多播委托

接下來我們來看一下什麽是多播委托

委托對象可使用 "+" 運算符進行合並。一個合並委托調用它所合並的兩個委托。只有相同類型的委托可被合並。"-" 運算符可用於從合並的委托中移除組件委托。

也就是說,可以將多個方法綁定給同一個委托

            DeleGreeting method = new DeleGreeting(MyGreeting.GreetingChinese);
            method += new DeleGreeting(MyGreeting.GreetingEnglish);
            MyGreeting.Greeting("李四", method);

結果:

技術分享圖片

c#之委托詳解