標籤:values 觸發器 nbsp 類型 console system 列印 handler 映射
C#命名空間下有五種類型,分別為:
類、構造、介面、枚舉、委託。
委託被定義為5中基本類型的一種,也就意味著代碼可以這麼寫:
using System;namespace Test{ delegate void PrintAny(); class Program { public PrintAny handler; void PrintNumber() { Console.WriteLine("1,2,3"); } static void Main(string[] args) { Program test_01 = new Program(); test_01.handler = test_01.PrintNumber; test_01.handler(); Console.Read(); } }}
簡單的測試後,可以看到輸出結果被列印出來。
接下來我來進一步說明什麼是委託。
第一步:委託的定義
百度的定義是——
委託是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞。
可以提取三個關鍵字:類、類型、傳遞方法
類和類型都有瞭解,那麼就來研究一下傳遞方法。
1-1、傳遞方法
一般編寫代碼的時候都是函數中傳遞各種參數,可以是數實值型別可以是物件類型;但是牽涉到需要對不同的程式碼片段進行選擇可能需要寫出長長的if..elseif..else 的選擇語句。
舉例說明
例如以下需求:
輸入:姓名、國籍 輸出:打招呼的方式。
分析:不同國家的人打招呼的方式是不一樣的,中國說“吃了嗎”、英國說“Hello”。
一般的代碼如下——
class GreetPeople { string Name; string Country; public GreetPeople(string name, string Country) { Name = name; } public void Greeting() { if (Country == "Enghlish") { EnglishGreeting(); } else if (Country == "Chinese") { ChineseGreeting(); } } public void EnglishGreeting() { Console.WriteLine(Name); Console.WriteLine("Hello"); } public void ChineseGreeting() { Console.WriteLine(Name); Console.WriteLine("吃了嗎"); } static void Main() { GreetPeople LiLei = new GreetPeople("LiLei", "English"); LiLei.Greeting(); Console.Read(); } }}
需求發生變更:
現在軟體將在20個不同語言的國家地區發布,現在請你對上面的代碼進行修改。你會發現你不僅僅要添加函數,同時不得不對Greeting
進行修改,長長的if-else if-else語句一向是不可靠的;調試20個國家的Geeeting函數將是一種折磨!!
現在引入委託,代碼如下:
delegate void GreetingHandler(); class GreetPeople { string Name; string Country; public GreetPeople(string name, string Country) { Name = name; } public void Greeting(GreetingHandler handler) { handler(); } public void EnglishGreeting() { Console.WriteLine(Name); Console.WriteLine("Hello"); } public void ChineseGreeting() { Console.WriteLine(Name); Console.WriteLine("吃了嗎"); } static void Main() { GreetPeople LiLei = new GreetPeople("LiLei", "English"); LiLei.Greeting(LiLei.EnglishGreeting); Console.Read(); } }
這個時候Greeting函數僅僅作為函數的觸發器,選擇是在Main第二行決定的作為建構函式的參數“English”並沒有提供有價值的資訊。這裡存在風險就是國家不容易寫錯但是調用的函數很可能不對。
代碼稍微修改了一下:
delegate void GreetingHandler(); class GreetPeople { string Name; string Country; private static Dictionary<string, GreetingHandler> CountryDic = new Dictionary<string, GreetingHandler>(); static GreetPeople() { CountryDic.Add("English", EnglishGreeting); CountryDic.Add("Chinese", ChineseGreeting); } public GreetPeople(string name, string country) { Name = name; Country = country; } public void Greeting() { GreetingHandler handler; Console.WriteLine(Name); if (CountryDic.TryGetValue(Country, out handler)) { handler(); } else { Console.WriteLine("未在該國發行!!"); } Console.WriteLine(); } public static void EnglishGreeting() { Console.WriteLine("Hello"); } public static void ChineseGreeting() { Console.WriteLine("吃了嗎"); } static void Main() { GreetPeople LiLei = new GreetPeople("LiLei", "English"); GreetPeople FeiFei = new GreetPeople("FeiFei", "Africa"); LiLei.Greeting(); FeiFei.Greeting(); Console.Read(); } }}
加了個字典將國家直接映射到對應的調用函數,調用Greeting的時候直接查字典調用即可。可以說,基本實現需求。
1-2、多播委託
現在需求又變了:
軟體賣的好將在多國會議展出,要求一次性給所有來賓打招呼;這個時候怎麼辦?
這就使用到了多播委託了;多播委託一次調用通知多個函數執行,代碼如下修改:
delegate void GreetingHandler(); class GreetPeople { string Name; string Country; private static Dictionary<string, GreetingHandler> CountryDic = new Dictionary<string, GreetingHandler>(); static GreetPeople() { CountryDic.Add("English", EnglishGreeting); CountryDic.Add("Chinese", ChineseGreeting); } public GreetPeople(string name, string country) { Name = name; Country = country; } public void Greeting() { GreetingHandler handler; Console.WriteLine(Name); if (Country == "All") { List<GreetingHandler> tempList = new List<GreetingHandler>(CountryDic.Values); if (tempList != null && tempList.Count > 0) { handler = tempList[0]; for (int i = 1; i < tempList.Count; i++) { handler += tempList[i]; } handler(); } } else if (CountryDic.TryGetValue(Country, out handler)) { handler(); } else { Console.WriteLine("未在該國發行!!"); } Console.WriteLine(); } public static void EnglishGreeting() { Console.WriteLine("Hello"); } public static void ChineseGreeting() { Console.WriteLine("吃了嗎"); } static void Main() { GreetPeople LiLei = new GreetPeople("LiLei", "English"); GreetPeople FeiFei = new GreetPeople("FeiFei", "Africa"); GreetPeople LeiJun = new GreetPeople("LeiJun", "All"); LiLei.Greeting(); FeiFei.Greeting(); LeiJun.Greeting(); Console.Read(); } }
C#委託(一)——說明及舉例