VB.NET - 成员事件处理的问题

时间:2009-10-26 12:22:21

标签: vb.net events constructor event-handling

我发现在构造函数中引发的事件(直接间接地)不能在类之外处理。为了证明这是否是实际问题,我写了一个简单的示例应用程序。

有关事件的类:

Namespace Utils
    Public Class A
        Public Event Test()

        Public Sub New()
            CallTest()
        End Sub

        Public Sub MakeACall()
            CallTest()
        End Sub

        Private Sub CallTest()
            RaiseEvent Test()
        End Sub
    End Class
End Namespace

主要表格(正确处理事件):

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click

        m_A.MakeACall()
    End Sub

    Private Sub HandleTest() Handles m_A.Test
        MsgBox("ta-dah!")
    End Sub

    Protected WithEvents m_A As New Utils.A()
End Class

主要表格(未正确处理事件):

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click

        m_A = New Utils.A()
    End Sub

    Private Sub HandleTest() Handles m_A.Test
        MsgBox("ta-dah!")
    End Sub

    Protected WithEvents m_A As Utils.A
End Class

在写完这些内容后,这种行为的原因变得非常明显,但也许有一种方法可以省略它?

2 个答案:

答案 0 :(得分:4)

这是处理此类情况的可接受模式:

  1. 实施ISupportInitialize
  2. 在您的EndInit方法中触发事件
  3. 如果有人在未初始化的情况下尝试使用您的类,则抛出InvalidOperationException
  4. 这是处理这种情况的一种非常通用的方式,而且序列化程序也尊重接口。

答案 1 :(得分:1)

如果这是一个仅限于Visual Basic的“问题”,我会感到惊讶;事实是,事件不能从尚未创建的对象中引发。只要你在里面构造函数,创建就没有完成。至少,这对我来说是有意义的,无论语言如何,似乎都是正确的。

不同的编制者可能不同意。

然而,所有表单以相同的方式(Init,Loading等)引发事件的事实相当表明这非常接近事实。威尔的答案为你的问题提供了一个很好的解决方案 - 当它归结为它时,根本不是问题:它只是对象的工作方式。

相关问题