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();
}
}

  

最新文章

  1. android rectF
  2. 解决android expandablelistview 里面嵌入gridview行数据重复问题
  3. 51nod1199 Money out of Thin Air
  4. Kali vmtools
  5. php服务器安装memcache
  6. ckrule规则编辑器在wpf中的使用
  7. poj3041,poj2226
  8. html ajax 双引号的问题
  9. 扔掉log4j、log4j2,自己动手实现一个多功能日志记录框架,包含文件,数据库日志写入,实测5W+/秒日志文件写入,2W+/秒数据库日志写入,虽然它现在还没有logback那么强大
  10. Spring读书笔记——bean解析
  11. respondsToSelector
  12. Git 的 WindowsXP安装
  13. float 为什么不能用== ,或者大于等于,或者小于等于
  14. Java Exception 和Error有什么区别?
  15. media(适配)
  16. chrome 常用插件集锦
  17. 016PHP基础知识——流程控制(四)
  18. Go - 切片(Slice)
  19. 001 KNN分类 最邻近算法
  20. 苏州Uber优步司机奖励政策(3月28日~3月30日)

热门文章

  1. 洛谷P2709 BZOJ 3781 小B的询问 (莫队)
  2. Shell-2-命令之乐
  3. Java泛型&lt;&gt;内各种参数的异同
  4. CentOs中Apache文件访问去除index.php
  5. Python——用os模块寻找指定目录(包括子目录)下所有图片文件
  6. loj #6235. 区间素数个数 min_12.5筛
  7. linux查找包含某个字符的文件并导出文件名
  8. 2.mybatis 的列名与数据库字段不对应
  9. react 的理念
  10. Codeforces-B-Divisors of Two Integers(思维技巧)