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. ubuntu17.04安装flash

    因为用不了软件商店(别问我为什么) 所以手动安装 1 下载文件 在firefox下下载  *****.tar.gz 压缩包 ,并解压(一般目录在 /home 当前用户下的 下载目录下) adobe官网 ...

  2. python之编辑器pycharm

    在进行python开发的时候,习惯使用pycharm这个编辑器进行开发工作,总结一些常用到的功能点 常用功能: 1. 打开当前文件所在的目录 在文件右击 -> Show in Exploer   ...

  3. Use Vim as a Python IDE

    Use Vim as a Python IDE I love vim and often use it to write Python code. Here are some useful plugi ...

  4. django 学习之DRF (一)

    Django框架基础DRF-01 前后端分离介绍 1.前后端不分离图解 2.前后端分离图解     3.为什么要学习DRF    DRF可以帮助我们开发者快速的开发⼀个依托于Django的前后后端分离 ...

  5. 通过IDEA及hadoop平台实现k-means聚类算法

    由于实验室任务方向变更,本文不再更新~ 有段时间没有操作过,发现自己忘记一些步骤了,这篇文章会记录相关步骤,并随时进行补充修改. 1 基础步骤,即相关环境部署及数据准备 数据文件类型为.csv文件,e ...

  6. 牛客国庆集训day6 B Board (模拟标记思维或找规律或分块???)

    链接:https://www.nowcoder.com/acm/contest/206/B来源:牛客网 题目描述 恬恬有一个nx n的数组.她在用这个数组玩游戏: 开始时,数组中每一个元素都是0. 恬 ...

  7. kindeditor使用记录

    --------------------------资源 百度下载包  kindeditor-4.1.11-zh-CN 解压后根据需要选择asp / asp.net / jsp / php 文件夹之一 ...

  8. Qt 学习之路 2(5):自定义信号槽

    Home / Qt 学习之路 2 / Qt 学习之路 2(5):自定义信号槽 Qt 学习之路 2(5):自定义信号槽  豆子  2012年8月24日  Qt 学习之路 2  131条评论 上一节我们详 ...

  9. C语言实践

    初学者往往有这样的困惑: 教程也阅读了,知识点也理解了,但是真正编写代码起来无从下手. 连一些基本的小程序都不能完成. 究其原因,就是缺少实践,没有培养起编程思维. 没有处理相关问题的经验. 编程能力 ...

  10. C#面试题-递归

    有一组数1.1.2.3.5.8.13.21.34...,求第n个数是多少? public int Recursion (int n){ ){ ; } &&n<=){ ; } )+ ...