委托背后的故事
来源:互联网 发布:淘宝投诉客服人工服务 编辑:程序博客网 时间:2024/04/30 14:21
委托背后的故事
学习过.NET的都知道,C#中引入了一种新的类型Delegate,也就是我们经常说的委托。委托到底是什么,大家都说它类似于指针,但是要比这些指针要安全。那么为什么要引入这个委托呢,今天我们就来看看委托的这点事儿!
委托前的蛮荒时代
我们大家都知道C语言中有一种很强大的武器就是指针,指针一个比较大的用处就是允许我们手动操作内存,这个是与托管代码的高级语言是一个主要的差别。我们都知道数据变量的内存地址可以存储在相应的指针变量中,同样函数的首地址也可以存储在某个函数指针变量里的。这样我们就可以通过这个函数指针变量来调用其所指向的函数了。一般情况下我们使用函数指针的情景如下代码所示,我们很少会直接将函数指针作为函数参数传递,但是有时候我们想在一个方法里调用客户传递的函数,通知客户我们进行了某项操作,以便让客户进行相应的业务操作。具体代码我就不给出了,老长时间不接触C都快忘光了,有兴趣的话可以自己查阅相关的资料。
void MyFun(int x); //这个申明也可写成:void MyFun( int );void (*FunP)(int ); //也可申明成void(*FunP)(int x),但习惯上一般不这样。int main(int argc, char* argv[]){ MyFun(10); //这是直接调用MyFun函数 FunP=&MyFun; //将MyFun函数的地址赋给FunP变量 (*FunP)(20); //这是通过函数指针变量FunP来调用MyFun函数的。}void MyFun(int x) //这里定义一个MyFun函数{ printf(“%d\n”,x);}
如果你感觉在C语言中传递函数作为参数没有什么应用市场,那么它在javascript中却无处不在,比如我们想在页面加载完成以后执行我们的业务逻辑,这个时候我们可以将封转了我们业务逻辑的函数,直接绑定到window的onload事件上,代码如下,这就是我们软件开发中最活跃的事件模型,不管是前台界面编程还是后台框架编程,事件模型都是十分有用的。
function pageLoadHandler() { //我们自己的业务逻辑 }; window.onload = pageLoadHandler;
如果你了解javascript面向对象编程,那么下边的代码你一定不会陌生,代码中我们为数组对象扩展了一个select函数,其根据客户传入的函数筛选所需的元素。你现在对这段代码是否感到似曾相识,如果还没有,就继续接着看下边的调用示例代码。对这跟C#中的拉姆达表达式很像,其实更应该说,前者像后者。
Array.prototype.select = function (filter) { var result = new Array(); for (var index = 0; index < this.length; i++) { if (filter.call(this, index, this[index])) { result.push(this[index]); }; }; return result; }; var array = new Array(); array.push(1); array.push(2); array.push(3); var selectedArray = array.select(function (index, item) { var result = false; if (item > 1) { result = true; }; return result; });
面向对象时代的委托
随着软件规模的不断扩大和软件开发方法学的发展,面向对象开发逐渐的取代了面向过程的开发。我们知道面向对象中的基本单位是对象,对象是数据和操作的组合体,对象封转了数据和操作,所有对数据和操作的调用都要经过对象进行交互。这样的话,很显然我们不能将函数直接作为参数传递了。作为一种新生代的语言,C#除了引入一些新的特性之外,同时也需要兼容一些已经存在的技术。那这个时候我们怎么办呢?
我们都知道既然方法都依附于某个对象,那么我们就可以定义一个类,来记录方法的相关信息,这样不仅保证了方法的唯一性,同时也提高了代码的安全性。所以在C#中引入了委托,委托是一种定义方法签名的类型。当实例化委托时,可以将其实例与任何具有兼容签名的方法相关联。我们可以通过委托实例调用方法。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。您可以创建一个自定义方法,当发生特定事件时某个类(例如 Windows 控件)就可以调用我们的方法。
public abstract class Delegate : ICloneable, ISerializable { // 摘要: // 初始化一个委托,该委托对指定的类实例调用指定的实例方法。 // // 参数: // target: // 类实例,委托对其调用 method。 // // method: // 委托表示的实例方法的名称。 // // 异常: // System.ArgumentNullException: // target 为 null。 - 或 - method 为 null。 // // System.ArgumentException: // 绑定到目标方法时出错。 protected Delegate(object target, string method); // // 摘要: // 初始化一个委托,该委托从指定的类调用指定的静态方法。 // // 参数: // target: // System.Type,它表示定义 method 的类。 // // method: // 委托表示的静态方法的名称。 // // 异常: // System.ArgumentNullException: // target 为 null。 - 或 - method 为 null。 // // System.ArgumentException: // target 不是 RuntimeType。请参见反射中的运行库类型。 - 或 - target 表示开放式泛型类型。 protected Delegate(Type target, string method); }
总结
其实,所谓委托就是在面向开发对象领域中,对传递函数作为参数的实现方式。它记录了方法所依附的对象及方法的相关信息。
- 委托背后的故事
- 强暴背后的故事
- 丁香花背后的故事
- 虚拟机背后的故事
- 成语背后的故事
- 卡农背后的故事
- HTML5背后的故事
- malloc背后的故事
- lena背后的故事
- ibatis背后的故事
- 面试背后的故事
- printf背后的故事
- 背后的故事
- 背后的故事
- 背后的故事
- 背后的故事
- 背后的故事
- printf背后的故事
- source insight 快捷键 汇总
- 转个 ubuntu 9.10 软件源 解决vsftpd 找不到问题
- Refactoring-Improving the Design of Existing Code——学习笔记(8)
- 黑马程序员 - Java - 常见的程序代码说明文档书写格式
- C++通过操作内存模拟序列化---实现多种类型的序列化(2)
- 委托背后的故事
- 通过SVN上传war文件至服务器并解压
- android学习笔记转--------------屏蔽返回键,home键以及其他实体按键
- jQuery插件TreeView异步加载树
- 转: Ubuntu 软件源分类
- 【排序算法】外部排序一 —— 外部排序介绍
- ubuntu-gcc 教程
- LINUX 常用命令汇总
- 【排序算法】外部排序二 —— 外部排序技术之多路归并