我是专门询问VB.NET,但我想其他语言的一般原则是相同的。我认为一个事件是.NET中的一流概念,但似乎reflection它只是一个特定方法,它在事件被引发时被调用。
AddHandler
和RemoveHandler
如何动态修改方法(AFAIK,事件为DynamicMethod
之前的事件?RaiseEvent
如何调用该方法?AddHandler
,RemoveHandler
和RaiseEvent
实现为语句而不是方法?答案 0 :(得分:2)
不,事件只是两个或三个方法的组合(“提升”部分是可选的),就像属性是一个或两个方法的组合一样。
AddHandler
和RemoveHandler
根本不会修改方法。他们只是调用事件的“添加”和“删除”部分,这些部分可用于实现部分。
通常,事件是通过引用具有适当委托类型的字段来实现的,Delegate.Combine
和Delegate.Remove
用于执行适当的操作。 (字段值将被更改 - 请记住委托类型是不可变的。)引发事件只需要调用委托。
至于为什么AddHandler
等是单独的语句类型 - 如果它们是方法,那么参数是什么?有些事情必须提到“事件”。基本上,AddHandler
语句对应于适当的事件“add”方法,就像属性提取对应于适当的属性“get”方法一样。您可以 通过EventInfo.AddHandler
进行反思。
请参阅我的article on delegates and events以获取更多可能有用的详细信息 - 它来自C#背景,但原则显然是相同的。
答案 1 :(得分:1)
事件只是一个代表。这里有一些代码可以像常规事件一样使用委托对象代替:
Module Module1
Sub Main()
Dim obj As New Example
obj.AnEvent = New EventHandler(AddressOf Handler)
obj.Test()
Console.ReadLine()
End Sub
Sub Handler(ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("got event")
End Sub
End Module
Class Example
Public AnEvent As EventHandler
Public Sub Test()
If AnEvent IsNot Nothing Then AnEvent(Me, EventArgs.Empty)
End Sub
End Class
但请注意此代码的问题。其他一些代码也可能与AnEvent混乱。喜欢替换它或将其设置为Nothing。这在任何情况下都是灾难性的,首先订阅事件的代码将停止正常工作。
VB.NET中的 Event 关键字可以防止这种情况发生。它包装委托对象,并使其他代码无法访问,超出了提供的关键字。与Property如何保护对字段的访问有些类似。 AddHandler和RemoveHandler确保现有注册不会消失。 RaiseEvent在不需要 Nothing 检查的情况下触发事件。