鉴于两个具有相同事件的类,我希望能够使用一个名称来引用它们。类似于以下内容:
Public Class myclass1
Public event1()
End Class
Public Class myclass2
Public event1()
End Class
在这里,我希望能够在运行时确定使用哪个类:
Sub somefunction(select as integer)
Dim voidclass
if select = 1 then
voidclass = myclass1
else
voidclass = myclass2
end if
AddHandler voidclass.event1, AddressOf eventhappened
End Sub
Sub eventhappened()
msgbox("Event occured")
End Sub
显然,这个示例可能有更好的方法,但我们假设类book1
已经存在,并且我的任务是创建book2
并且只修改somefunction
而不修改book1
本身。
上面的例子应该导致错误event1
不是'对象'的事件。
看起来属性和方法很好,但事件不是。在这种情况下如何处理事件?
答案 0 :(得分:2)
该代码段与此问题不符。它有一个奇怪的错误,类中的事件未声明Shared
,因此代码必须使用适当的对象引用。不是类型名称。也许答案很简单:
Private obj1 As myclass1
Private obj2 As myclass2
Sub somefunction(select as integer)
If select = 1 Then
AddHandler obj1.event1, AddressOf eventhappened
Else
AddHandler obj2.event1, AddressOf eventhappened
End If
End Sub
但可能真正的问题是相同的情况,但现在变量声明为:
Private obj1, obj2
无法输入,因此Object
。是的,VB.NET不支持。与VB.NET中的大多数怪癖一样,这背后有历史。 VB从未支持事件的显式后期绑定,只支持方法和属性。旧版本中的方案非常古怪。您必须使用WithEvents
关键字声明变量,并为事件处理程序选择一个特定名称。换句话说:
Dim WithEvents obj1
Sub obj1_somethinghappened
'' handles the event1 event for obj1
End Sub
或者换句话说,所有事件都是迟到的。这个方案没有被转移到VB.NET中,它有太多实际问题。 WithEvents
仍然存在,但现在需要方法声明中的Handles
关键字。这不符合你的意愿。
VB.NET设计者故意没有为AddHandler
语句添加后期绑定支持。我不知道他们决定这个的确切原因,只能猜测。没有技术原因无法添加,只需要编译器生成反射代码。一种可能的解释是他们认为它太贵了。另一个原因是他们认为当方法签名不匹配时难以解释时会引发运行时异常。我最喜欢最后一个,它们非常难看。
你必须使用Reflection来获得你想要的东西。使用obj1.GetType()。GetEvent(“event1”)获取EventInfo,使用Get / AddMethod()添加事件处理程序。
Fwiw,C#语言在其动态关键字实现中支持这一点。也许你可以通过asking for the feature在他们的耳边放一个小虫。如果以前要求的话,不知道。
答案 1 :(得分:1)
您可以为事件定义接口并在类中实现它,然后您可以通过接口引用订阅此事件。见下文:
Public Interface INotifier
Event SomethingHappened()
End Interface
Public Class Class1
Implements INotifier
Public Event SomethingHappened() Implements INotifier.SomethingHappened
End Class
Public Class Class2
Implements INotifier
Public Event SomethingHappened() Implements INotifier.SomethingHappened
End Class
Module Module1
Dim notifiers As List(Of INotifier) = New List(Of INotifier) From
{
New Class1(),
New Class2()
}
Sub Main()
SubscribeToEventHandler(0)
End Sub
Private Sub SubscribeToEventHandler(ByVal index As Integer)
Dim notifier As INotifier = notifiers(index)
AddHandler notifier.SomethingHappened, AddressOf EventHandler
End Sub
Private Sub EventHandler()
End Sub
End Module