c#之委托详解(Delegate)
一、委托的概念
在我们学习委托之前,我们来了解下,什么是委托呢?
官方概念:委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似。与 C 中的函数指针不同,委托是面向对象的、类型安全的和保险的。委托的类型由委托的名称定义。
很多初学者都看不懂官方的概念,一脸懵逼。
举个例子吧:有几个小伙伴在外面玩,突然有两个人手机忘记带了,并且两个人家距离很近,其中一个人想要骑车回去拿,另一个不想回去,就委托另一个帮他拿。
其实委托就是一个类型,它所实例化的变量就是委托类型的变量,也可以说委托是一个方法的模板,当我们去掉delegate关键字的时候,就像是一个没有方法体的方法。
二、委托声明语法
delegate <return type> <delegate-name> <parameter list>
三、接下来我们来看下委托三部曲
public class MyDelegate
{
////1、委托的声明
public delegate void NoReturnNopara();
public static void show()
{
//2、委托的实例化
NoReturnNopara method = new NoReturnNopara(Study); //3、委托的调用
method.Invoke();
}
public static void Study()
{
Console.WriteLine("正在学习delegate!");
}
}
然后我们调用show方法来看一个结果:
结果没毛病。
四、委托的用途
接下来我们来思考下,这样用委托有什么意义呢?还不如直接 MyDelegate.Study(); 这样。
当然我们学习委托并不是简单的像上面一样,上面只是为了便于我们学习了解委托而已。接下来我们来看一个打招呼的例子:
public class MyGreeting
{
public static void GreetingChinese(string name)
{
Console.WriteLine("{0},早上好",name);
}
public static void GreetingEnglish(string name)
{
Console.WriteLine("{0},good morning",name);
}
}
上面是中国人和外国人打招呼的方式,那个问题来了,我们怎么确定打招呼的人是中国人还中外国人呢?简单,我们定义一个枚举然后判断一个不就ok了嘛。
public class MyGreeting
{public static void Greeting(string name,PeopleType type)
{
switch (type)
{
case PeopleType.Chinese: Console.WriteLine("{0},早上好", name);
break;
case PeopleType.English: Console.WriteLine("{0},good morning", name);
break;
}
}
}
public enum PeopleType
{
Chinese,
English
}
这种做法满足了我们的需求。但是我们应该有所发现,这个方法的可扩展性很差,日后我们要是又有一个需求,要添加日本人打招呼,韩国人打招呼怎么办?我们就不得不修改枚举和Greeting这个方法内的代码,真是糟糕逶了。
那么,我们就应该想其它的方法来解决这个问题。从而达到”对扩展开方,对修改封闭“的原则。怎么实现呢?我们可以不管是哪国人,只负责打招呼就好,将打招呼的逻辑做为参数。
首先,我们先定义一个打招呼的委托。
public delegate void DeleGreeting(string name);
然后将这个委托做为参数传给 Greeting(string name,DeleGreeting greeting) 这个方法,让这个方法来调用打招呼。
public static void Greeting(string name,DeleGreeting greeting)
{
greeting.Invoke(name);
}
最后,我们来实例化这个委托,并调用这个方法。
static void Main(string[] args)
{
DeleGreeting method = new DeleGreeting(MyGreeting.GreetingChinese);
MyGreeting.Greeting("张三",method); DeleGreeting method1 = new DeleGreeting(MyGreeting.GreetingEnglish);
MyGreeting.Greeting("lucy", method1); Console.Read();
}
结果如下:
用这种方式实现的话,以后不管你添加多少种国家的打招呼。都不用去改动 Greeting(); 这个方法,只需要扩展一个打招呼的方法就行了。达到”对扩展开方,对修改封闭“的原则。
五、多播委托
接下来我们来看一下什么是多播委托
委托对象可使用 "+" 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。
也就是说,可以将多个方法绑定给同一个委托
DeleGreeting method = new DeleGreeting(MyGreeting.GreetingChinese);
method += new DeleGreeting(MyGreeting.GreetingEnglish);
MyGreeting.Greeting("李四", method);
结果:
c#之委托详解(Delegate)的更多相关文章
- C#委托详解(3):委托的实现方式大全(续)
接上篇(C#委托详解(2):实现方式大全),本篇继续介绍委托的实现方式. 4.Action<T>和Func<T>委托 使用委托时,除了为每个参数和返回类型定义一个新委托类型之外 ...
- C#委托详解(2):实现方式大全
本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等. 接上篇(C#委托详解(1):什么是委托)介绍完什么是委托之后,来看看C ...
- C#事件与委托详解
from https://www.cnblogs.com/sjqq/p/6917497.html C#事件与委托详解[精华 多看看] Delegatedelegate是C#中的一种类型,它实际上是一个 ...
- JavaScript 事件委托详解
基本概念 事件委托,通俗地来讲,就是把一个元素响应事件(click.keydown......)的函数委托到另一个元素: 一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事 ...
- C#委托详解(1):什么是委托
本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等. 什么是委托? 委托是寻址方法的.NET版本,使用委托可以将方法作为参数 ...
- c# 委托详解
1.委托声明 2.委托入门实例 namespace ConsoleApplication1 { public delegate void methodDelegate(string str); cla ...
- C# 委托详解(一)
1.委托简单例子 class eeProgram { // 声明delegate对象 public delegate string CompareDelegate(int a, int b); // ...
- C#事件与委托详解【精华 多看看】
Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类.与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持有与 ...
- Kotlin属性委托系统总结与提供委托详解
属性委托总结回顾: 在前三次已经将Kotlin委托相关的知识点进行了完整的学习了,具体博文如下: https://www.cnblogs.com/webor2006/p/11369019.html h ...
随机推荐
- redux进阶 --- 中间件和异步操作
你为什么需要异步操作? https://stackoverflow.com/questions/34570758/why-do-we-need-middleware-for-async-flow-in ...
- [问题解决]Fresco设置圆角效果不生效问题探究
[问题解决]Fresco设置圆角效果不生效问题探究 /** * Created by diql on 2017/2/21 11:07:04. */ 问题 在View中设置: fresco:rounde ...
- Git学习系列之Git基本操作提交项目(图文详解)
前面博客 Git学习系列之Git基本操作克隆项目(图文详解) 然后可以 cd 切换到 LispGentleIntro 目录, 新增或者修改某些文件.这里只是模拟一下操作, 实际情况可能是 使用 Ecl ...
- JavaScript设计模式-4.继承和聚合
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 在超链接href中实现form的提交
<form name="form1" method="post" action=""> <div class=" ...
- WebLogic 数据源密码加密
先启动域:
- JetBrains 产品激活码
激活码 K03CHKJCFT-eyJsaWNlbnNlSWQiOiJLMDNDSEtKQ0ZUIiwibGljZW5zZWVOYW1lIjoibnNzIDEwMDEiLCJhc3NpZ25lZU5hb ...
- web工程中文字符乱码:try { res.setContentType("text/html;charset=gbk"); PrintWriter pw=res.getWriter(); ;;; }
输入正确的name ,pwd 跳转到main 页面 证明:登录信息确认基本正确 用户名,密码不对时提示:信息错误 注意编码格式: 应设置如下:在try中设置字符编码为gbk,在try外有时出错,设置 ...
- Codeforces F. Cowmpany Cowmpensation
Description 有一棵树,现在要给每个节点赋一个在1到D之间的权值,问有多少种方案满足任意一个节点的权值都不大于其父亲的权值. n<=3000,D<=1e9 题面 Solution ...
- 初识JSP,第一天
1.什么JSP java Server Page java 服务端的页面,它和servlet 一样可以提供动态的html 响应. 不同的是 servlet 以 java 代码 为主 jsp 以html ...