VB.NET - проблема с обработкой событий участника - PullRequest
0 голосов
/ 26 октября 2009

Я обнаружил, что событие, вызванное (непосредственно косвенно) в конструкторе, не может быть обработано вне самого класса. Чтобы доказать, что это была настоящая проблема, я написал простое примерное приложение.

Класс с событием:

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 ]

4 голосов
/ 26 октября 2009

Это приемлемый шаблон для обработки ситуаций такого типа:

  1. Реализация ISupportInitialize
  2. Запустите ваши события в вашем методе EndInit
  3. Бросьте исключение InvalidOperationException, если кто-то попытается использовать ваш класс без его инициализации

Это довольно универсальный способ решения подобных ситуаций, плюс сериализаторы также уважают интерфейс.

1 голос
/ 26 октября 2009

Я был бы удивлен, если бы это была проблема, ограниченная Visual Basic; Дело в том, что событие не может быть вызвано объектом, который еще не был создан. Пока вы внутри конструктора, создание еще не завершено. По крайней мере, это имело бы смысл для меня и, казалось бы, сохранялось независимо от языка.

Различные компиляторы могут не соглашаться.

Однако тот факт, что все формы вызывают события одинаково (Init, Loading и т. Д.), Довольно показательно, что это довольно близко к истине. Ответ Уилла дает отличное решение вашей проблемы, которая, когда дело доходит до нее, вовсе не является проблемой: это просто способ работы объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...