开发者

How can I handle an event that's raised in New?

开发者 https://www.devze.com 2023-03-30 00:36 出处:网络
Testcase: Public Class T Public Event A() Public Sub New() RaiseEvent A() End Sub End Class Module Module1 Sub Main()

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
0

精彩评论

暂无评论...
验证码 换一张
取 消