在 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。这导致界面状态不一致,并在更新程序集时崩溃。