首页 > 代码库 > C#委托(一)——说明及举例
C#委托(一)——说明及举例
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#委托(一)——说明及举例