随手复习一下委托:delegate
先骂个街,天儿太闷了……
随手复习一下委托,delegate 是一种函数指针,是 .net 提供的一种安全的函数指针,翻译的也很贴切,像是委托人,又像代理人,通过“委托”来执行一些函数而不是直接调用它。因为 C# 中委托被实现为指针链表,所以委托可以加入多个函数,一次性一块儿执行。
举个花生:小明(中国教育中最频繁出镜的绝对明星,不知为什么,我脑子里直觉般闪现第一个名字就是它,我Kao)要给他妈买酱油(貌似这个例子在多年前我自己的帖子里出现过),妈妈对小明的调用就表示为:
public class 妈妈
{
酱油 Get酱油()
{
var 孩子 = new 小明();
retu 小明.打酱油();
}
}
小明打酱油
当妈妈需要酱油时候,可以随时召唤小明去卖,那么如果需要盐呢、醋呢,假设 小明 都提供这样的方法,那么妈妈调用时候不得不这样:
public class 妈妈
{
调料 Get调料()
{
var 多种调料 = new 调料集合();
var 孩子 = new 小明();
调料集合.Add(小明.打酱油());
调料集合.Add(小明.买醋());
调料集合.Add(小明.买盐()); return 多种调料;
}
}
小明要买多种调料
事情到了现在,有两个很明显的问题:
1. 妈妈直接对小明进行了操作,这不是聪明的编码方式,因为如果妈妈还有闺女小红呢?让小红再去买东西就需要修改大量的妈妈类中的代码,显然很二。
2. 代码中规定了方法里只能调用小明三个技能,再多加两个或少买一个呢,就必须重新修改源代码了,所以不能做到动态的增减技能。
说到这里好像跑题去谈如何构建程序了,显然我还没到那个水平,回到委托,如果使用委托,至少可以同时解决这两个主要问题,因为:
1. 委托是“中间人”,妈妈可以全心关注对委托的控制,比如增加和减少要购买的东西
2. 委托是“相对抽象”的,妈妈通过委托既可以选择小明去买,也可以选择小红去买,一定程度上的解耦
用委托改一下,依旧忽略细节,只领会精神:
public class 妈妈
{
delegate 调料 买调料委托();
private 买调料委托 妈妈让孩子去买调料;
} public static class 小明
{
public static 调料 打酱油(){}
public static 调料 买醋(){}
public static 调料 买盐(){}
} public static class 小红
{
public static 调料 打酱油(){}
public static 调料 买米(){}
public static 调料 买油(){}
}
妈妈用委托
妈妈定义了一个“买调料”的委托,只要孩子有和这个委托签名一致的技能,妈妈就可以使用。有了这个基础,妈妈再考虑买调料时候就人性化的多,比如 1 日要买酱油、醋和米,就可以这样:
妈妈让孩子去买调料 = new 买调料委托(小明.打酱油);
妈妈让孩子去买调料 += 小明.买醋();
妈妈让孩子去买调料 += 小红.买米();
妈妈让孩子去买调料();
妈妈自由组合买东西
妈妈把分属于两个孩子的三个技能添加到了委托,妈妈只需要运行这个委托,就可以运行一次买到三个东西,2 日妈妈不再需要买米而需要买盐时,就可以这样:
妈妈让孩子去买调料 -= 小红.买米();
妈妈让孩子去买调料 += 小红.买盐();
去掉米添上盐
从语法上来说我觉得已经比较人性化了,下面放上两个简单的示意代码,描述一下对委托的增减:
delegate void OnEventDelegate(string text);
OnEventDelegate OnEventHandler; private void button1_Click(object sender, EventArgs e)
{
if (OnEventHandler == null)
{
OnEventHandler = new OnEventDelegate(ShowLabel1);
OnEventHandler += ShowLabel2;
OnEventHandler += ShowLabel3;
OnEventHandler += ShowLabel4; MessageBox.Show(string.Format("delegate object count: {0}", OnEventHandler.GetInvocationList().Count()));
}
} private void button2_Click(object sender, EventArgs e)
{
if (null != OnEventHandler)
{
foreach (var method in OnEventHandler.GetInvocationList())
{
MessageBox.Show(string.Format("delegate has method cout: {0}, now remove : {1}", OnEventHandler.GetInvocationList().Count(), method.Method.Name)); OnEventHandler -= (OnEventDelegate)method; if (null == OnEventHandler)
{
MessageBox.Show("delegate remove all method");
break;
}
}
}
} private void button3_Click(object sender, EventArgs e)
{
var timeString = DateTime.Now.Second.ToString();
OnEventHandler(timeString);
}
对委托的增减操作
随手复习一下委托:delegate的更多相关文章
- [.NET] C# 知识回顾 - 委托 delegate (续)
C# 知识回顾 - 委托 delegate (续) [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6046171.html 序 上篇<C# 知识回 ...
- [C#] C# 知识回顾 - 委托 delegate
C# 知识回顾 - 委托 delegate [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6031892.html 目录 What's 委托 委托的属性 ...
- C# 委托Delegate(一) 基础介绍&用法
本文是根据书本&网络 前人总结的. 1. 前言 定义&介绍: 委托Delegate是一个类,定义了方法的类型, 使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的 ...
- 为什么不能把委托(delegate)放在一个接口(interface)当中?
stackoverflow上有人问,为什么不能把委托放在一个接口当中? 投票最多的第一个答案第一句话说,“A Delegate is just another type, so you don't g ...
- C# 代理/委托 Delegate
本文转载自努力,努力,努力 1. 委托的定义:委托是函数的封装,它代表一"类"函数.他们都符合一定的签名:拥有相同的参数列表,返回值类型.同时,委托也可以看成是对函数的抽象,是函数 ...
- c# 委托 delegate
委托是一种存储函数引用的类型,在事件和事件的处理时有重要的用途 通俗的说,委托是一个可以引用方法的类型,当创建一个委托,也就创建一个引用方法的变量,进而就可以调用那个方法,即委托可以调用它所指的方法. ...
- 理解委托(delegate)及为什么要使用委托
理解委托(delegate)及为什么要使用委托 委托:是一种定义方法签名的类型. 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联. 您可以通过委托实例调用方法. 上述为官方说法,理解起来 ...
- 深入理解委托(Delegate)
前言 委托其实一直以来都感觉自己应该挺熟悉的,直到最近又去翻了翻 CLR via C#,感觉我之前的理解可能还有失偏颇.在这记录一下. 之前文章的链接: 接口和委托的泛型可变性 C#高级编程笔记 De ...
- C# -- 使用委托 delegate 执行异步操作
C# -- 使用委托 delegate 执行异步操作 委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似. 与 C 中的函数指针不同,委托是面向对象的.类型安全的和保险的. 委托的 ...
随机推荐
- 【Android界面实现】可旋转的汽车3D模型效果的实现
转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 今天要给大家介绍的是怎样实现可旋转的汽车3D模型. 先看实现效果 这仅仅是静态图,实际上,这个模型是能够依据 ...
- C++ Primer第九章课后编程问题
1. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3V1Z2xlMjAxMA==/font/5a6L5L2T/fontsize/400/fill/I0J ...
- IOS的UITextField,UIButton,UIWebView它描述的一些属性和IOS提示图像资源
有时UI要开发的资源与实际frame不符.这一次,我们要绘制图片 UIImage* image = [[UIImage imageNamed:@"text_field_bg.png" ...
- 使用ArcGIS API for Silverlight 进行复合多条件空间查询
原文:使用ArcGIS API for Silverlight 进行复合多条件空间查询 这两天帮网上认识的一个兄弟做了一个查询的示例,多多少少总结一下,在此和大家分享. 为什么说是复合多条件呢?因为进 ...
- [CLR via C#]5.4 对象哈希码和dynamic基元类型
原文:[CLR via C#]5.4 对象哈希码和dynamic基元类型 FCL的设计者认为,如果能将任何对象的任何实例放到一个哈希表集合中,会带来很多好处.为此,System.Object提供了虚方 ...
- CSDN博客频道维护公告
各位亲爱的用户: 为了给大家提供更稳定的使用环境,2014年4月23日23点至04月24日1点(本周四凌晨)博客频道server将进行维护,维护期间不能正常訪问.给大家带来不便,敬请广大 ...
- ASP.NET学习笔记2--自己写代码绑定Gridview
像以前一样,先写好自己的样式布局, 第二步,在数据库建立一个商品表 代码如下: CREATE TABLE [SHANGPING_INFO] ( [Shangping_Id] INT PRIMARY K ...
- ftk学习记录(IME文章)
[声明:版权全部,欢迎转载.请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前面说的是全屏设置,还是请大家看一下效果图. watermark/2/text/aHR0cDovL ...
- 《MonkeyRunner原理剖析》第九章-MonkeyImage实现原理 - 概览
MonkeyRunner没有引进Junit等单元测试框架,所以没有相应的断言方法来去对测试结果进行判断. 但MonkeyRunner提出了另外一个判断执行结果成功与否的方法,那就是通过截图比对.毕竟M ...
- SQL Server 2012的附件失败,与硬链接的问题
1.我在系统上做了硬链接,也就是把C盘的某个目录,映射为D盘. 2.把数据库文件mdf和ldf放入D盘.结果,SQL Server的企业管理器,无法从D盘里加载mdf或ldf文件,并且在目录下无法显示 ...