AD:
委托是可用于调用其他对象方法的对象。它们有时被称为类型安全函数指针,因为它们与其他编程语言中所使用的函数指针相似。但不同于函数指针,VB.NET 委托是基于 System.Delegate 类的引用类型,它可以引用共享方法—无需特定的类实例即可调用的方法和实例方法。
委托在调用过程和被调用过程需要媒介的情况下是很有用的。例如,您可能想让一个引发事件的对象能够在不同的环境下调用不同的事件处理程序。不幸的是,引发事件的对象无法提前知道处理特定事件的事件处理程序。Visual Basic .NET 通过在使用 AddHandler 语句时创建委托,可让您动态地将事件处理程序与事件关联。在运行时,委托将各种调用转发到相应的事件处理程序。
尽管可以创建自己的委托,但在大多数情况下,Visual Basic .NET 为您创建委托并提供具体信息。例如,Event 语句将名为 <EventName>EventHandler 的委托类隐式定义为 Event 语句所在类的嵌套类,且其签字与该事件相同。AddressOf 语句则隐式创建委托的实例。例如,以下两行代码是等效的:
- AddHandlerButton1.Click
- AddressOfMe.Button1_Click
- 'AddHandler指向引发事件的对象,AddressOf则确定该事件对象所要调用的事件处理程序
- '上述行为又可以称为监视
- AddHandlerButton1.Click,NewEventHandler(AddressOfButton1_Click)
只要编译器可以用上下文确定委托的类型,就可以使用速写方法创建委托。
注:处理自基类继承的事件
派生类(继承某个基类特征的类)能用 Handles MyBase 语句处理它们的基类所引发的事件。
处理来自基类的事件
通过给事件处理程序过程的声明行添加 Handles MyBase.<event name> 语句来声明派生类中的事件处理程序,其中的 event name 是基类中正在处理的事件的名称。例如:
- PublicClassClass1
- PublicEventSE(ByValiAsInteger)
- 'Placemethodsandpropertieshere.
- EndClass
- PublicClassClass2
- InheritsClass1
- SubEventHandler(ByValxAsInteger)HandlesMyBase.SE
- 'PlacecodetohandleeventsfromClass1here.
- EndSub
- EndClass
声明使用现有委托类型的事件
某些情况下,可能会要声明某事件使用现有委托类型为基础委托。以下语法说明了进行声明的方式:
Event AnEvent As DelegateType该语法在将多个事件路由到同一处理程序时是很有用的,不过使用现有委托类型时需要先进行如下定义:
- delegate{sub|function}DelegateType(参数1,参数2)
下面是vb.net控制台程序演示单一事件委托多处理程序.
比如说在社会上,你是法律,社会上有三种人,警察、无赖和自愿反扒队。
你规定:如果小偷偷东西,则警察处罚小偷500元钱,自愿反扒队要打无赖进医院一次
这就是现实中的委托。
实际上,在写程序中,程序员就是法律,警察、小偷和自愿反扒队就是三个对象。小偷偷东西是一个方法,小偷还有一个偷东西事件,他偷东西激发这个事件。而警察和自愿反扒队就是两个事件处理对象,警察负责把小偷的钱扣除500,自愿反扒队需要大小偷进医院一次。
所以,委托有如下几个要素:
- 激发事件的对象--就是小偷
- 处理对象事件的对象--就是警察和自愿反扒队
- 定义委托,就是法律让警察和自愿反扒队监视小偷。
如果这三个要素都满足的话,则你就写出了一个完整事件的处理。
下面是vb.net控制台的实例
- ImportsSystem
- ModuleModule1
- '准备引用无赖类的偷东西事件
- PublicWithEventswAs无赖
- SubMain()
- Console.WriteLine("新的一天开始了....")
- '实例华警察、无赖、自愿反扒队类
- DimpAsNew警察
- w=New无赖
- DimppAsNew自愿反扒队
- '设置对无赖类的偷东西事件的监视,并设置相应的事件处理程序
- '如果小偷玩偷东西则引用警察的罚钱处理程序
- AddHandlerw.PlayGame,AddressOfp.扣钱
- '如果小偷偷东西则引用自愿反扒队的打人处理程序
- AddHandlerw.PlayGame,AddressOfpp.打人
- w.偷东西()
- Console.WriteLine("天黑了....")
- Console.ReadLine()
- EndSub
- 'EndClass
- PublicClass警察
- SubNew()
- Console.WriteLine("生成警察......")
- EndSub
- '定义的事件处理程序的参数类型要与定义的委托的参数类型相一致
- PublicSub扣钱(ByValsenderAsObject,ByValeAsSystem.EventArgs)
- Console.WriteLine("警察:好小子,胆敢偷东西...")
- '定义线程输出迟缓3秒
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("警察:看看你小子有多少钱...")
- DimfAs无赖=sender
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("无赖的钱:"+f.钱.ToString())
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("开始扣钱......")
- System.Threading.Thread.Sleep(3000)
- f.钱=f.钱-500
- Console.WriteLine("扣完了....现在无赖还剩下:"+f.钱.ToString())
- System.Threading.Thread.Sleep(3000)
- EndSub
- EndClass
- PublicClass无赖
- '先定义一个偷东西的事件使用现有委托类型PlayGameHandler为基础委托
- PublicEventPlayGameAsPlayGameHandler
- Privatem_MoneyAsInteger
- PrivateeyAsInteger
- SubNew()
- Console.WriteLine("生成无赖....")
- m_Money=1000
- ey=5
- EndSub
- '定义挨打属性用来记录挨打过几次
- Property挨打()AsInteger
- Get
- Returney
- EndGet
- Set(ByValValueAsInteger)
- ey=Value
- EndSet
- EndProperty
- '定义前属性用来记录有多少钱
- Property钱()AsInteger
- Get
- Returnm_Money
- EndGet
- Set(ByValValueAsInteger)
- m_Money=Value
- EndSet
- EndProperty
- '定义偷东西过程
- PublicSub偷东西()
- Console.WriteLine("无赖开始偷东西了")
- System.Threading.Thread.Sleep(3000)
- '实例化事件参数
- DimeAsNewSystem.EventArgs
- '引发偷东西事件,参数类型要与现有委托类型一致
- RaiseEventPlayGame(Me,e)
- EndSub
- EndClass
- PublicClass自愿反扒队
- SubNew()
- Console.WriteLine("自愿反扒队来了.....")
- System.Threading.Thread.Sleep(3000)
- EndSub
- '定义的事件处理程序的参数类型要与定义的委托的参数类型相一致
- PublicSub打人(ByValsenderAsObject,ByValeAsSystem.EventArgs)
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("自愿反扒队:好小子,敢偷东西...")
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("自愿反扒队:你小子挨过几次打了...")
- DimbnAs无赖=sender
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("无赖:"+bn.挨打.ToString+"次")
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("自愿反扒队:那也得揍你,先来一拳....")
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("自愿反扒队:再来一脚......")
- System.Threading.Thread.Sleep(3000)
- Console.WriteLine("自愿反扒队:打完了...赶紧去医院吧...")
- EndSub
- EndClass
- '定义委托类型
- DelegateSubPlayGameHandler(ByValsenderAsObject,ByValeAsSystem.EventArgs)
- EndModule