【问题标题】:VB.NET - problem with member's event handlingVB.NET - 成员事件处理问题
【发布时间】:2009-10-26 12:22:20
【问题描述】:

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

参加活动的班级:

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

写完这些文章后,这种行为的原因变得很明显,但也许有办法省略它?

【问题讨论】:

    标签: vb.net events constructor event-handling


    【解决方案1】:

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

    1. 实施ISupportInitialize
    2. 在 EndInit 方法中触发事件
    3. 如果有人尝试使用您的类而不进行初始化,则抛出 InvalidOperationException

    这是处理此类情况的一种非常通用的方式,而且序列化程序也尊重接口。

    【讨论】:

      【解决方案2】:

      如果这是仅限于 Visual Basic 的“问题”,我会感到惊讶;事实上,事件不能从尚未创建的对象中引发。只要您在构造函数内部,创建还没有完成。至少,这对我来说是有道理的,而且无论语言如何似乎都是正确的。

      不同的编译器可能不同意。

      但是,所有表单都以相同的方式(初始化、加载等)引发事件的事实相当表明这非常接近事实。威尔的回答为您的问题提供了一个很好的解决方案——当它真正解决时,这根本不是问题:这只是对象的工作方式。

      【讨论】:

      • 从来没有真正考虑过,因为我从来没有尝试过从构造函数中引发事件。每天我们都会学到一些新东西;)
      • 顺便说一句,微软认为类似的情况是一个错误:support.microsoft.com/kb/832793
      猜你喜欢
      • 1970-01-01
      • 2019-08-03
      • 1970-01-01
      • 1970-01-01
      • 2012-04-30
      • 2011-05-16
      • 2011-01-23
      相关资源
      最近更新 更多