委托和 AddressOf 运算符

更新:2007 年 11 月

委托是可用于调用其他对象方法的对象。由于它们与其他编程语言中所使用的函数指针相似,因此它们有时也被称为“类型安全的函数指针”。但与函数指针不同的是,Visual Basic 委托是基于 System.Delegate 类的引用类型。委托可以引用共享方法(无需类的特定实例便可调用的方法)和实例方法。

委托和事件

委托在调用过程和被调用过程需要媒介的情况下是很有用的。例如,您可能想让一个引发事件的对象能够在不同的环境下调用不同的事件处理程序。遗憾的是,引发事件的对象无法提前知道哪个事件处理程序正在处理特定的事件。Visual Basic 可在您使用 AddHandler 语句时为您创建委托,从而使您可以动态地将事件处理程序与事件关联起来。在运行时,委托将各种调用转发到相应的事件处理程序。

虽然您可以创建自己的委托,但在大多数情况下,Visual Basic 为您创建委托并保管详细信息。例如,Event 语句将名为 <EventName>EventHandler 的委托类隐式定义为 Event 语句所在类的嵌套类,且其签字与该事件相同。AddressOf 语句则隐式创建委托的实例。例如,以下两行代码是等效的:

AddHandler Button1.Click, AddressOf Me.Button1_Click
' The previous line of code is shorthand for the next line of code.
AddHandler Button1.Click, New EventHandler(AddressOf Button1_Click)

只要编译器可以用上下文确定委托的类型,就可以使用速写方法创建委托。

声明使用现有委托类型的事件

某些情况下,可能会要声明某事件使用现有委托类型为基础委托。以下语法说明了进行声明的方式:

Delegate Sub DelegateType()
Event AnEvent As DelegateType

该语法在将多个事件路由到同一处理程序时是很有用的。

委托变量和参数

可以将委托用于其他非事件相关任务(如自由线程处理),或用于编译时需调用不同函数版本的过程。

例如,假设您有一个分类广告应用程序,其中包含一个汽车名称列表框。广告按标题进行排序,这些标题则通常都是汽车的品牌。某些汽车的名称所含年份早于该品牌出现的年份时您就会遇到问题。问题在于列表框内置的排序功能只使用字符代码排序;它将以日期开头的广告放在前面,后面是以品牌开头的广告。

若要解决这一问题,可以在某个类中创建一个排序过程,该类在多数列表框中使用标准字母排序,但是它可以在运行时切换为汽车广告的自定义排序。要达到这一目的,可以使用委托在运行时将自定义排序过程传递给排序类。

每个委托类都定义一个被传递对象方法规范的构造函数。委托构造函数的参数必须是对方法或 lambda 表达式的引用。

若要指定对方法的引用,请使用下面的语法:

AddressOf [expression.]methodName

expression 的编译时类型必须是类或接口的名称,而该类或接口包含签名与委托类的签名相匹配的指定名称的方法。methodName 可以是共享方法,也可以是实例方法。即使为类的默认方法创建了委托,methodName 也不是可选项。

若要指定 lambda 表达式,请使用下面的语法:

Function ([parm As type, parm2 As type2, ...]) expression

函数的签名必须与委托类型的签名相匹配。有关 lambda 表达式的更多信息,请参见 lambda 表达式

请参见

任务

如何:在 Visual Basic 中将过程传递给另一过程

如何:调用委托方法

如何:编写事件处理程序

概念

lambda 表达式

事件和事件处理程序

AddHandler 和 RemoveHandler

多线程应用程序

参考

Delegate 语句

AddressOf 运算符