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#委托(一)——说明及举例的更多相关文章

  1. [.net 面向对象编程基础] (21) 委托

    [.net 面向对象编程基础] (20)  委托 上节在讲到LINQ的匿名方法中说到了委托,不过比较简单,没了解清楚没关系,这节中会详细说明委托. 1. 什么是委托? 学习委托,我想说,学会了就感觉简 ...

  2. 关于C# 委托(delegate)与事件(event)的用法及事例

    C#中的委托和事件对于新手可能会有一点难理解,所以先从一个小例子入手,以便能更好的理解其如何使用.有一个学生每天定闹钟在早上6点起床,所以当每天早上6点的时候,闹钟就会响起来,从而学生才会按时起床. ...

  3. Linq lambda 匿名方法

    课程6 委托.匿名方法.Lambda表达式.Linq查询表达式 上课日志1 一.委托的基本认识 提问:能不能把方法作为参数传递??? 也即是能不能声明一个能存放方法的变量呢——委托. 委托是一种数据类 ...

  4. 反射基础 System.Reflection

    一.获取程序集Assembly 1.获取当前运行的程序集 System.Reflection.Assembly[] asm = AppDomain.CurrentDomain.GetAssemblie ...

  5. C#委托举例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  6. javascript举例介绍事件委托的典型使用场景

    在了解什么是DOM事件以及给DOM事件绑定监听器的几种方法后,我们来谈谈事件委托. 1. e.target 和 e.currentTarget 当我们给目标元素target 绑定一个事件监听器targ ...

  7. C#委托的一次"甜蜜"接触

    委托是个说烂了的话题,但是依旧有好多人不知道为什么要在C#中使用委托,最近有朋友也问到我这个问题,所以举例些场景,以供那些知道怎么声明委托.怎么调用却不知道为什么要用的朋友一些参考,当然也是希望验证下 ...

  8. jQuery-1.9.1源码分析系列(十) 事件系统——事件委托

    jQuery的事件绑定有几个比较优秀的特点: 1. 可以绑定不限数量的处理函数 2. 事件可以委托到祖先节点,不必一定要绑到对应的节点,这样后添加的节点也照样能被处理. 3. 链式操作 下面主要分析事 ...

  9. [.net 面向对象程序设计进阶] (5) Lamda表达式(一) 创建委托

    [.net 面向对象程序设计进阶] (5) Lamda表达式(一)  创建委托 本节导读: 通过学习Lambda表达式,学会创建委托和表达式目录树,深入了解Lambda的特性,让你的代码变的更加清晰. ...

随机推荐

  1. UWP&WP8.1 基础控件——Border

    border 是边框控件 border是UWP和WP8.1最常用的控件之一. border字面意义是用来添加边框的. 基础用法 <border BorderThickness="1&q ...

  2. 正经学C#_运算符优先级:[c#入门经典]

    学了那么多的运算符,终于差不多结束了,现在要说一下  总体的优先级别 高到低的顺序 类别  运算符  结合性  前缀 ++,--,(),+,-,!,~ 从左到右  乘除  * / %  从左到右  加 ...

  3. UINavigationController + UIScrollView组合,视图尺寸的设置探秘(二)

    承接上文,我想把view布局修改为如下模式,让ScrollView长在NavigationBar的下方,这总不会有遮挡的问题了吧: story board内容如下,主要是右侧视图蓝色区域添加了Scro ...

  4. Installing the .NET Framework 3.5 on Windows 8, Windows 8.1 and Windows 10

    Installing the .NET Framework 3.5 on Windows 8, Windows 8.1 and Windows 10 .NET Framework (current v ...

  5. H - the Sum of Cube(水题)

    A range is given, the begin and the end are both integers. You should sum the cube of all the intege ...

  6. java基础之变量和常量、类型转换

    一.     变量 变量是可改变的量,每赋个值便会开辟一个新内存地址. 1.首先,变量需要一个声明,例如:int a,这个a也可以当作是一个标签,它指向了一个内存地址,这个地址是属于int类型的套餐, ...

  7. [SinGuLaRiTy] NOIP 膜你赛-Day 2

    [SinGuLaRiTy-1031] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 对于所有题目: Time Limit: 1s | Mem ...

  8. Nodejs 文档概览

    Node.js v8.11.1 Node.js v8.11.1 文档 今天大致浏览了一下Node.js的官方文档,走马观花的了解了大部分模块的api,对他们的使用场景做一个简单的笔记 assert 断 ...

  9. Java框架之单元测试

    单元测试dao层 @Test   //1.要写 test public void TestUserDao(){ ApplicationContext ctx=new ClassPathXmlAppli ...

  10. 智能合约安全事故回顾(2)-BEC溢出攻击

    讲溢出攻击之前,先给大家讲个故事:2014年的时候,美国的宾夕法尼亚州的某个小镇上发生了一个乌龙事件,征兵系统对一万多名1893年到1897出生的男子发去信函,要求他们注册参军,否则面临罚款和监禁.收 ...