[C#参考]委托机制
1. 委托概述
这是一个新的概念,但是其本质并不是什么新鲜的事物,委托本质上就是一个类。只不过一般的类是数据的集合,委托保存的是一个或者多个方法。委托是引用类型,因此委托有引用和对象,同时委托对象中包含指向方法的引用,也就是C++中的函数指针的概念。也就是说委托中的数据成员都是一些函数指针,这些函数指针指向的方法和委托类型有相同的函数签名。

从上图中可以看出,委托和类基本上就是一个东西,过程都是一样的:
声明一个类型->声明该类型的引用变量(在栈中)->利用new在堆中创建实例对象,同时利用构造函数传参数,只不过委托实例利用默认的构造函数初始化调用列表->使用变量,通过引用变量,使用该类型的对象。

类对象的数据部分保存的是一般的数据类型 ,委托对象的数据部分保存的是函数指针,这些函数指针挨着盘的存放,构成了调用列表。
2. 声明委托类型
委托是类型,就好像类是类型一样,所以委托类型必须在被用来创建引用变量以及类型的对象之前声明。
delegate void MyDel(int x);
//其中的MyDel就是委托类型名,类似于类名
注意:委托的类型声明,不需要在类内部声明,因为委托类型和类是同一个级别的。

3. 创建委托对象
委托是引用类型的,因此有引用和对象,就像上图中所示,引用变量存在栈内存中,委托对象存在堆内存中。
MyDel delVar;
//委托变量的声明,也就是委托引用
委托对象的创建:
delVar = new MyDel(myIntsObj.methodName);
dVar = new Mydel(SClass.staticMethodName);
//使用new关键字创建委托对象,同时给委托类型的默认构造函数传一个方法名作为参数。
//这个方法名就是委托对象调用列表中的第一个成员的方法的名字。
提示:在创建委托对象的时候有快捷的语句
delVar = myIntsObj.methodName;
dVar = SClass.staticMethodName;
这是因为方法名称和其相对应的委托类型之间有隐式的转换。

图中的Invocation list里面存储的都是一些函数指针。
当然上面的创建对象可以在一条语句上完成:
MyDel delVar = new MyDel(myIntsObj.methodName);
MyDel dVar = new Mydel(SClass.staticMethodName);
或者:
MyDel delVar = myIntsObj.methodName;
MyDel dVar = SClass.staticMethodName;
4. 委托赋值
由于委托是引用类型的,可以通过给它赋值来改变包含在委托变量中的引用。旧的委托对象会被垃圾回收器回收。
MyDel delVar; delVar = myIntsObj.methodName;
.
.
delVar = SClass.staticMethodName;

注意:这里用到了C#垃圾回收器的知识。
5. 修改委托
事实上,委托是恒定的,委托对象被创建后就不会再改变。任何对委托对象的修改都是创建一个新的委托,同时按照要求修改这个新委托对象的调用列表。
组合委托:
MyDel delA = myIntsObj.methodName;
MyDel delB = SClass.staticMethodName;
MyDel delC = delA + delB;//组合调用列表

委托增加和删除方法:
MyDel delVar = inst.MyM1;//创建并初始化
delVar += SCL.m3;//增加方法
delVar += X.Act;//增加方法

delVar -= SCL.m3;//从委托移除方法

6. 调用委托
试图调用空的委托对象会抛出异常,所以每次调用委托对象的时候,把委托对象和null进行比较,来判断委托对象的调用列表是否为空。
注意:
委托引用变量没有被初始化前,委托引用是null。委托对象中的调用列表为空,那么委托引用也为null。
调用方法是直接用委托引用,加上相对应的参数:
if(delVar != null)
{
delVar(55);
}

补充的知识点:
1. 当调用带返回值的委托对象时,调用列表中最后一个方法返回的值就是委托调用的返回值,调用列表中其他所有的方法的返回值都会被忽略。只是返回值被忽略,方法的操作还是有效果的(比如对全局变量的修改)。
2. 如果委托有引用参数,参数值会根据调用列表中的一个或多个方法的返回值而改变。在调用委托列表中的下一个方法时,参数的新值(不是初始值)会传给下一个方法。
[C#参考]委托机制的更多相关文章
- 【Unity3D技巧】在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信 (二) : 引入中间层NotificationCenter
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 一对多的观察者模式机制有什么缺点? 想要查看 ...
- C++模拟C#事件委托机制(一)
原文来自于http://www.cnblogs.com/netssfy/articles/1652671.html 写了一段时间的C#代码后确实发现C#的事件委托非常好用.于是便想是否在C++中也能如 ...
- Javascript事件模型系列(二)事件的捕获-冒泡机制及事件委托机制
一.事件的捕获与冒泡 由W3C规定的DOM2标准中,一次事件的完整过程包括三步:捕获→执行目标元素的监听函数→冒泡,在捕获和冒泡阶段,会依次检查途径的每个节点,如果该节点注册了相应的监听函数,则执行监 ...
- Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论
Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...
- Java虚拟机JVM学习05 类加载器的父委托机制
Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...
- Invoke() 方法是 Unity3D 的一种委托机制
Invoke() 方法是 Unity3D 的一种委托机制 如: Invoke("SendMsg", 5); 它的意思是:5 秒之后调用 SendMsg() 方法: 使用 Inv ...
- java类加载器学习2——自定义类加载器和父类委托机制带来的问题
一.自定义类加载器的一般步骤 Java的类加载器自从JDK1.2开始便引入了一条机制叫做父类委托机制.一个类需要被加载的时候,JVM先会调用他的父类加载器进行加载,父类调用父类的父类,一直到顶级类加载 ...
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- JavaScript 之默认行为 DOM2级,事件委托机制
1. 事件默认行为及阻止方式 1.1 浏览器的默认行为 JavaScript事件本身所具有的属性,例如a标签的跳转,Submit按钮的提交,右键菜单,文本框的输入等. 1.2 ...
随机推荐
- Redhat Linux内核升级全记录(转)
http://www.sina.com.cn 2001/06/15 15:38 中国电脑教育报 李红 Redhat Linux因为比较容易上手,所以用户很多.它系统配置完善,预装了丰富的应 ...
- Android 在一个程序中启动另一个程序
Android 开发有时需要在一个应用中启动另一个应用,比如Launcher加载所有的已安装的程序的列表,当点击图标时可以启动另一个应用.一般我们知道了另一个应用的包名和MainActivity的名字 ...
- Hibernate 配置详解(12) 补充
hibernate.hbm2ddl.import_files_sql_extractor 这个配置项用于补充这篇文章: http://blog.csdn.net/stefwu/article/deta ...
- Java图形化界面设计——布局管理器之FlowLayout(流式布局)
一.布局管理器所属类包 所属类包 布局管理器名称 说明 Java.awt FlowLayout(流式布局) 组件按照加入的先后顺序按照设置的对齐方式从左向右排列,一行排满到下一行开始继续排列 Bord ...
- HEVC与VP9编码效率对比
HEVC(High EfficiencyVideo Coding,高效率视频编码)是一种视频压缩标准,H.264/MPEG-4 AVC的继任者.目前正在由ISO/IEC MPEG和ITU-T VCEG ...
- java之Set源代码浅析
Set的接口和实现类是最简单的,说它简单原因是由于它的实现都是基于实际的map实现的. 如 hashSet 基于hashMap,TreeSet 基于TreeMap,CopyOnWriteArraySe ...
- 理解Android的layout和measure
在Android UI开发中,总会有情况需要自定义View和View Group. 什么是View?就是Android中一个基本视图单位,一个Button是一个view, 一个Layout, 也是一个 ...
- foundation 框架 NSString常用总结(二)
以此作为NSString常用总结(一)的补充 NSString* str = [NSString stringWithFormat:@"I love programing! You, com ...
- 【Web】十步教你搭建完整免费的个人网站(花生壳+XAMPP+WordPress)
1.从花生壳官网(http://www.oray.com/peanuthull/download.php)下载最新版本的客户端. 下载完成后安装,注册护照(需手机验证码验证),注册完成后获取免费域名并 ...
- JavaScript属性中的offsetLeft、offsetWidth、clientWidth、scrollLeft、scrollWidth、innerWidth
1.offsetLeft和offsetTop 只读属性,返回当前元素与父辈元素之间的距离(不包括边框).其中父辈元素的取法是有门道的: (1).若父辈元素中有定位的元素,那么就返回距离当前元素最近的定 ...