委托介绍
当.NET小组的设计师开始设计新的框架时,他们知道要为回调的实现提供广泛的支持。他们从正反两面比较用函数指针还是接口来实现回调方法。最后,他们决定建立一种新的混合技术,该技术结合了使用接口的类型安全(type safety)和多态性与使用函数指针的高效率和适应性。这种新技术反映一种革新,就是我们所知道的委托。
在.NET框架的编程模型中委托是一个特殊的类型。.NET框架的设计师添加了委托用于提供一种方便的把一个或多个处理方法连接到通知源的绑定机制。你将看到,委托能实现你用接口或函数指针实现的相同类型的回调设计。但是基于委托的回调设计通常只需更少的代码,并且比基于接口和函数指针的回调设计提供了更多特征。
在Visual Basic .NET中你能使用Delegate关键字定义一个委托类型。每个委托定义必须包括类型名称和提供给处理方法的调用特征(signature)。下面是三个委托类型定义:
Delegate Sub BaggageHandler()
Delegate Sub MailHandler(ItemID As Integer)
Delegate Function QuoteOfTheDayHandler(Funny As Boolean) As String
如上所示,定义委托类型的调用特征使用了标准的Visual Basic的定义方法的语法。象方法一样,委托类型必须使用Sub或Function关键字定义。在参数列表和返回值方面委托定义也与方法定义相近。
当你编译包含委托类型定义的代码时,Visual Basic .NET编译器在后台为你做了很多额外的工作。编译器为每个委托类型生成一个类定义(class definition)。为委托类型生成的类都是从System.Multicast委托继承来的可重建的类。图1是前面的三个委托类型定义在编译后的情形,该透视图来自ILDASM.EXE。

图1:编译后的委托类型
我们看一下图1中的委托类型QuoteOfTheDayHandlerl的定义。你能发现除了建立一个从 MulticastDelegate继承来的类之外,Visual Basic .NET编译器还添加了一个公共的构造函数和三个公共的方法,分别叫Invoke、BeginInvoke和EndInvoke。
Visual Basic .NET编译器为每个委托定义添加了一个公共的构造函数使它成为一个可重建类型。该公共的构造函数是一个叫.ctor的成员函数。一旦你承认委托是个可重建类型,就容易理解它怎样在应用程序中使用。使用委托编程需要从委托类型中建立委托对象,并且每个类型对象都必须用这种方法建立,这样它才能被初始化指向目标方法的实现。等一会你将看到怎样编写代码建立委托对象并绑定到目标处理方法。
编译器在产生委托类型定义的时候,除了添加一个公共的构造函数外,还自动添加了一个叫Invoke的公共方法。提供Invoke方法使通知源能够执行委托对象所绑定的目标处理方法。当你在委托对象上调用Invoke方法时,它简单地将调用转发给目标处理方法。
QuoteOfTheDayHandler类型的Invoke方法的调用特征与委托类型本身的调用特征相匹配,这一直是随着委托类型定义的。编译器产生Invoke方法时,该方法的调用特征与委托类型所包含的调用特征相匹配,任何传递进Invoke调用的参数将被路由到目标处理方法的调用。如果目标处理方法包含输出参数或返回值,这些值将返回到委托对象的Invoke方法的调用者。
你可能注意到QuoteOfTheDayHandler类型的定义包含两个编译器产生的方法,分别叫 BeginInvoke和EndInvoke。这两个方法为异步执行一个独立的线程中的委托对象的目标处理方法提供了基础。委托可以异步执行几个事务的特征使它们功能更加强大。
