编程VB.NET 开发人员

在 Visual Basic 中如何实现事件和委托的工作,以及它们在标准事件和用户事件之间的使用场景有何不同?

用 Hintsage AI 助手通过面试

答案。

在 Visual Basic (VB.NET) 中,委托 是一种包含对具有特定签名的方法的引用的类型,并且是事件处理的基础。事件 基于委托,允许对象通知其他对象发生的变化。

对于标准事件,使用已定义的委托,例如 EventHandler,而对于用户事件,则可以定义具有所需签名的自定义委托:

'声明自定义委托和事件 Public Delegate Sub ChangedEventHandler(sender As Object, e As EventArgs) Public Event Changed As ChangedEventHandler '使用事件 Public Sub OnChanged() RaiseEvent Changed(Me, EventArgs.Empty) End Sub

细节

  • 事件只能在声明它的类内部调用;
  • 可以组合委托,创建调用链;
  • 不遵循正确的签名会导致编译错误。

反转问题。

为什么在 Visual Basic 中无法在类外调用事件,即使它被声明为 Public?

回答: 尽管有 Public 访问修饰符,但事件只能在类外进行“订阅”或“取消订阅”,却只能在类内调用(RaiseEvent)——这是语言的特性,确保了封装性和对事件分发的控制。例如:

Public Class Foo Public Event MyEvent() End Class Dim f As New Foo() ' 这样是不可以的:f.RaiseEvent MyEvent() — 编译器不允许这样做。

由于不了解主题的细节而产生的真实错误实例。


故事

Windows Forms 项目: 开发者试图在数据类外调用事件“DataUpdated”以更新 UI。失败了,事件未被处理,只能重构架构,因对事件可见性理解错误而重新设计逻辑。


故事

Web 服务: 在声明委托时,遗漏了签名中的一个变量。事件已订阅,但调用时出现运行时错误——订阅者期望一个参数,但调用时传递了两个。


故事

1C 插件: 开发者使用 FieldInfo.SetValue 模拟调用 RaiseEvent。这导致界面状态不一致,并在更新程序集时崩溃。