ПрограммированиеVB.NET разработчик

Опишите механику событий (Events) в Visual Basic и приведите пример создания собственного события. На что стоит обратить внимание при декларации и подписке?

Проходите собеседования с ИИ помощником Hintsage

Ответ

В Visual Basic события (Events) позволяют объекту оповещать другие компоненты приложения о произошедших изменениях. Событие объявляется через ключевое слово Event. Его вызывают с помощью метода RaiseEvent (VB.NET) или Raise (VB6), а компоненты могут на него подписаться (Handles/WithEvents).

Пример VB.NET:

Public Class Worker Public Event WorkCompleted As EventHandler Public Sub DoWork() ' ...какая-то работа RaiseEvent WorkCompleted(Me, EventArgs.Empty) End Sub End Class Public Class Manager Private WithEvents w As Worker Public Sub New() w = New Worker() End Sub Private Sub w_WorkCompleted(sender As Object, e As EventArgs) Handles w.WorkCompleted Console.WriteLine("Работа завершена!") End Sub End Class

Важные моменты:

  • Событие можно вызвать только в том же классе, где оно объявлено
  • Если событие имеют аргументы, их типы должны быть строго определены
  • WithEvents можно использовать только с полями и свойствами класса
  • Подписавшись на событие, не забывайте отписываться при необходимости (например, чтобы избежать утечек памяти)

Вопрос с подвохом

Можно ли объявить событие с модификатором доступа Private и подписаться на него из другого класса?

Ответ: Нет, модификатор Private ограничивает область видимости события только тем классом, где оно объявлено. Другие классы не увидят его, следовательно, не смогут подписаться.

Примеры реальных ошибок из-за незнания тонкостей темы


История

В крупном приложении события создавали с модификатором Public, но нигде явно не отписывались от них. При долгой работе приложения это приводило к утечкам памяти, так как обработчики ссылались на ненужные объекты.


История

В миграции с VB6 на VB.NET разработчик ожидал, что событие будет доступно во всех модулях, но по умолчанию событие было Friend. В результате обработчик не срабатывал, и этот баг нашли только на интеграционных тестах.


История

Программист ошибся в сигнатуре делегата события — переставил местами sender и e. Не было ни одного сообщения об ошибке (event handler просто не вызывался), а необходимая бизнес-логика пропускалась скрыто до полуфинального релиза.