zoukankan      html  css  js  c++  java
  • 委托背后的故事

    委托背后的故事

             学习过.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中却无处不在,比如我们想在页面加载完成以后执行我们的业务逻辑,这个时候我们可以将封转了我们业务逻辑的函数,直接绑定到windowonload事件上,代码如下,这就是我们软件开发中最活跃的事件模型,不管是前台界面编程还是后台框架编程,事件模型都是十分有用的。       

            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);

          }

    总结

             其实,所谓委托就是在面向开发对象领域中,对传递函数作为参数的实现方式。它记录了方法所依附的对象及方法的相关信息。

  • 相关阅读:
    494 Target Sum 目标和
    493 Reverse Pairs 翻转对
    492 Construct the Rectangle 构建矩形
    491 Increasing Subsequences 递增子序列
    488 Zuma Game 祖玛游戏
    486 Predict the Winner 预测赢家
    485 Max Consecutive Ones 最大连续1的个数
    483 Smallest Good Base
    Django Form组件
    Django Auth组件
  • 原文地址:https://www.cnblogs.com/wufengtinghai/p/2551570.html
Copyright © 2011-2022 走看看