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#参考]委托机制的更多相关文章

  1. 【Unity3D技巧】在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信 (二) : 引入中间层NotificationCenter

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 一对多的观察者模式机制有什么缺点? 想要查看 ...

  2. C++模拟C#事件委托机制(一)

    原文来自于http://www.cnblogs.com/netssfy/articles/1652671.html 写了一段时间的C#代码后确实发现C#的事件委托非常好用.于是便想是否在C++中也能如 ...

  3. Javascript事件模型系列(二)事件的捕获-冒泡机制及事件委托机制

    一.事件的捕获与冒泡 由W3C规定的DOM2标准中,一次事件的完整过程包括三步:捕获→执行目标元素的监听函数→冒泡,在捕获和冒泡阶段,会依次检查途径的每个节点,如果该节点注册了相应的监听函数,则执行监 ...

  4. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  5. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  6. Invoke() 方法是 Unity3D 的一种委托机制

    Invoke() 方法是 Unity3D 的一种委托机制 如: Invoke("SendMsg", 5);   它的意思是:5 秒之后调用 SendMsg() 方法: 使用 Inv ...

  7. java类加载器学习2——自定义类加载器和父类委托机制带来的问题

    一.自定义类加载器的一般步骤 Java的类加载器自从JDK1.2开始便引入了一条机制叫做父类委托机制.一个类需要被加载的时候,JVM先会调用他的父类加载器进行加载,父类调用父类的父类,一直到顶级类加载 ...

  8. Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架

    类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...

  9. JavaScript 之默认行为 DOM2级,事件委托机制

    1. 事件默认行为及阻止方式    1.1 浏览器的默认行为       JavaScript事件本身所具有的属性,例如a标签的跳转,Submit按钮的提交,右键菜单,文本框的输入等.    1.2 ...

随机推荐

  1. “-Xmx1024m -Xms1024m -Xmn512m -Xss256k”——Java运行参数(转)

    JVM的堆的内存, 是通过下面面两个参数控制的 -Xms 最小堆的大小, 也就是当你的虚拟机启动后, 就会分配这么大的堆内存给你 -Xmx 是最大堆的大小 当最小堆占满后,会尝试进行GC,如果GC之后 ...

  2. Umbraco学习1------安装

    最近在做一个公益项目,考虑到成本和性价比,最终决定还是选用Umbraco作为CMS平台进行开发. 顺便也借机将Umbraco的使用整理成系列,便于以后的记忆. Umbraco的所有信息,基本都可以在h ...

  3. MySQL Binlog的介绍

    binlog基本定义:二进制日志,也成为二进制日志,记录对数据发生或潜在发生更改的SQL语句,并以二进制的形式保存在磁盘中: 作用:MySQL的作用类似于Oracle的归档日志,可以用来查看数据库的变 ...

  4. openstack windows 2008 img

    1,制作镜像主机pre Env yum -y install qemu-img virt-install libvirt 2,配置bridge

  5. Uber在华从沸点到冰点 搞定这些才能继续走下去

    腾讯科技 蒋栩根 5月6日报道 五一前夕,本应坐等笑看小长假带来的喜人业绩的Uber被广州市工商.交委.公安部门的联合检查当头浇了一盆冷水,也被戴上了一顶“涉嫌非法运营”的帽子.而一天前,它才与广物汽 ...

  6. Android 类似未读短信图标显示数字效果的分析

    之前一直以为是应用本身在对图标进行修改,看了源码之后发现其实主要的工作并不是应用自己完成的,主要的工作在是launcher里面完成的. 关于系统里面类似未读短信的具体处理流程如下, 原理 一个应用要实 ...

  7. 提前防止Non-PIE错误,检测app是否包含PIE标志

    //Howard 2013-07-19 //如何检测app是否包含PIE标志? 答:使用xCode自带的otool工具. otool程序在Xcode.app/Contents/Developer/us ...

  8. zoj 2966 Build The Electric System

    就是套了个prim算法就ac了 #include <stdio.h> #include <string.h> #define MaxInt 0x3f3f3f3f #define ...

  9. 初识EF

    1. EF是Entity Framework的缩写,全称是(ADO.Net Entity Framework),是以ADO.Net为基础所发展出来的对象关系对应(O/R Mapping)解决方案,早起 ...

  10. UIImage缩放

    +(UIImage *)scaleImage: (UIImage *)image scaleFactor:(float)scaleFloat { CGSize size = CGSizeMake(im ...