Testcase:
Public Class T
Public Event A()
Public Sub New()
RaiseEvent A()
End Sub
End Class
Module Module1
Sub Main()
Dim obj = New T()
AddHandler obj.A, AddressOf handleA
End Sub
Sub handleA()
Debug.WriteLine("!")
End Sub
End Module
Of course AddHandler
hasn't run yet when New
is fired.
So I tried like this:
Public Cl开发者_如何学运维ass T
Public Event A()
Public Sub New()
RaiseEvent A()
End Sub
End Class
Module Module1
Dim WithEvents obj As T
Sub Main()
obj = New T()
End Sub
Sub handleA() Handles obj.A
Debug.WriteLine("!")
End Sub
End Module
But even here it seems the handler isn't registered until after New
has completed.
However, in real life the event is raised within code that's semantically part of the object initialisation, and I'd really rather not have to create some Initialize
function.
Do I have any other option?
It makes no sense to put code which raises an event within a constructor, unless some other code which executes within the same constructor is able to register to handle the event (e.g. through some indirect method call). That in turn would require leaking Me
before the constructor has completed, which is generally a bad idea.
Basically: try to avoid this design. During construction an object shouldn't be visible to the outside world, and that includes event handlers.
I agree with Jon about putting events into constructors - specifically because the standard event pattern does expose the instance of the sender in the event call and, as Jon rightly says, this is a bad idea.
However, it's not a bad idea if you only pass out values. And you can do that easily.
Try this:
Public Class T
Public Sub New(a As Action)
a()
End Sub
End Class
Module Module1
Sub Main()
Dim obj = New T(AddressOf handleA)
End Sub
Sub handleA()
Debug.WriteLine("!")
End Sub
End Module
精彩评论