C#委托



Windows API经常使用C语言风格的函数指针来创建称为回调函数或简称为回调的实体。使用回调,windows开发者可以处理按钮单击、鼠标移动、菜单选择以及内存中两个实体间的双向通信。

.NET Framework里,回调功能则由更为安全和面向对象的委托(delegate)来完成。本质上来讲,委托是一个类型安全的对象,它指向程序中另一个以后会被调用的方法(或多个方法)

委托有许多用途,但它们的大多数用于事件处理和线程。


1.定义委托类型

C#中创建一个委托类型时,使用delegate关键字,委托的名称可以自由选择。例如:

public delegate intBinaryOp(int x, int y);


C#编译器处理委托类型时,它先自动产生一个派生自System.MulticasrDelegate的密封类。这个类与它的基类System.Delegate一起为委托提供必要的基础设施,以维护以后将要调用方法的列表。如下图所示,我们通过菜单栏“工具”-ILDasm”工具来查看BinaryOp委托。可以看到,为生成的BinaryOp类定义了三个公共方法:Invoke()BeginInvoke()EndInvoke()



Invoke()是核心方法,因为它用来以同步方式调用委托对象维护的方法。这里的同步就是指调用者必须等待方法调用完毕后才能继续执行。但在C#中,我们不直接调用Invoke()方法,而是使用适当地C#语法使得Invoke()在后台调用(下面会举例说明)。

BeginInvoke()EndInvoke()方法能在第二个执行线程上异步调用当前的方法。尽管.NET基础类库为多线程专门提供了整个命名空间(System.Threading),而委托顺带就提供了这一功能。

请注意,由Invoke()方法定义的参数和返回值完全匹配BinaryOp委托类型。BeginInvoke()成员前面的参数也基于BianryOp委托,但BeginInvoke()方法将总是提供最后两个参数(AsyncCallback类型和object类型),而且返回IAsyncResult接口,用于异步方法调用。最后,EndInvoke()方法的返回值类型与定义的委托返回类型相同,且总是以一个实现了IAsyncResult接口的对象作为唯一的参数。


2. 最简单的委托示例

如下面示例所示,我们定义了一个参数和返回类型都为doubleProcessDelegate委托,另外又定义了两个与委托有相同返回类型和参数列表的函数MultipleDivide。在Main函数中使用新的委托类型声明了一个委托变量process,后将Multiple函数引用赋给process委托变量。注,必须使用new关键字创建一个委托。

尽管一般在C#应用程序中不显示调用Invoke()方法,但是我们也完全可这么做,例如“Console.WriteLine("Result is {0}", process(10, 2)); ”,我们也可以写成“Console.WriteLine("Result is {0}", process.Invoke(10, 2));  ”

<span style="font-size:14px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Delegate
{
    class Program
    {
        //定义一个委托
        delegate double ProcessDelegate(double param1, double param2);

        //Multiply函数
        static double Multiply(double param1, double param2)
        {
            return param1 * param2;
        }

        //Divide函数
        static double Divide(double param1, double param2)
        {
            return param1 / param2;
        }

        static void Main(string[] args)
        {
            //声明一个ProcessDelegate委托类型的变量
            ProcessDelegate process;

            //初始化委托为Multiply函数的引用
            process = new ProcessDelegate(Multiply);

            //通过委托调用委托所引用的函数
            Console.WriteLine("Result is {0}", process(10, 2));

            //改变委托的为Divide函数的引用
            process = new ProcessDelegate(Divide);
            Console.WriteLine("Result is {0}", process(10, 2));

            Console.ReadKey();
        }
    }
}</span>


其运行结果为:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值