c#之委托詳解
一、委托的概念
在我們學習委托之前,我們來了解下,什麽是委托呢?
官方概念:委托是一種安全地封裝方法的類型,它與 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#之委托詳解