用面向对象思维理解.NET委托:函数是对象、委托是函数对象的类型


    不谈C/C++,就从对象和类型考虑.NET委托(delegate),笔者的看法是:函数是对象、委托是函数对象的类型。

    教科书上讲:具有同属性的实体抽象成类型。那么,程序代码中函数的属性是啥?就是函数签名,即函数返回类型、函数参数类型。进一步,具有相同属性的函数抽象成啥呢?就是.NET中所谓的委托(delegate),它就是函数的类型。与普通对象与类型不同,委托的对象(函数)可以不要new操作符号创建,因为函数已经存在于代码中。委托自己没有成员,它只是一类函数的代表而已,所以叫做delegate,也可翻译成代表。

    举一个把函数作为参数调用的例子。

    int fun2(int n)
    {
        int m = 0;
        for(int k = 1; k <= n; k++)
        {
           m += k * k;
        }
        return m
    }

    int fun3(int n)
    {
        int m = 0;
        for(int k = 1; k <= n; k++)
        {
           m += k * k * k;
        }
        return m
    }

    函数fun2计算1到n的平方和,函数fun3计算1到n的立方和。它们的属性相同:返回int、参数int。于是定义这两个函数的类型——一个委托TSum如下。注意,TSum是类型(Type),其返回类型、参数类型与fun2、fun3相同。

    public delegate int TSum(int n);

    这样,就可以定义调用函数的函数output(),如:

    void output(TSum sum)
    {    
        MessageBox.Show(sum(10).ToString());
    }

    最后,用 output(fun2)、output(fun3),将显示10以内平方数和、立方数和。当然,如果完全按照面向对象方式,可以先创建两个TSum实例,然后调用,如:

    TSum f2 = new TSum(fun2);
    TSum f3 = new TSum(fun3);
    output(f2);
    output(f3);

    后一种方式产生的f2、f3在内部机制上与output(fun2)、output(fun3)有较大的区别,详细阐述见Jeffrey Richter的名著《框架设计(第2版:CLR Via C#》。

    .NET事件机制也可以理解:事件是函数、委托规定了函数的属性。在激发事件时,必须判断事件是否注册,即实现如下类似代码:

    if(OnClickEvent != null) // 相当于判断 OnClickEvent 对象是否存在
    {
       OnClickEvent(this, new ClicktEventArgs(...));
    }

    刚接触.NET时,总觉得委托delegate难以理解,笔者认为关键原因是:没有从面向对象的观点上考虑函数与委托的关系,而是从传统的C/C++、函数指针、函数回调、调用安全、事件机制等方面讲委托。事实上,从面向对象的观点看,函数是实体,那么就可认为是对象,再抽象就成函数类型——委托了。这样想,许多原先模糊的观念就清晰多了。

http://blog.csdn.net/hulihui/article/details/2873519

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值