我在问具体的VB.NET,但我想象一般原则在其他语言中是一样的。我认为一个事件是.NET中的一流概念,但从reflection看来,它只是一个特定的方法,它在事件引发时被调用。如何实施事件
- 如何
AddHandler
和RemoveHandler
修改方法动态(据我所知,事件pre-日期DynamicMethod
S' - 如何
RaiseEvent
调用的方法? - 为什么
AddHandler
,RemoveHandler
,并RaiseEvent
实现陈述而不是方法?
我在问具体的VB.NET,但我想象一般原则在其他语言中是一样的。我认为一个事件是.NET中的一流概念,但从reflection看来,它只是一个特定的方法,它在事件引发时被调用。如何实施事件
AddHandler
和RemoveHandler
修改方法动态(据我所知,事件pre-日期DynamicMethod
S'RaiseEvent
调用的方法?AddHandler
,RemoveHandler
,并RaiseEvent
实现陈述而不是方法?不,一个事件只是两个或三个方法的组合(“raise”部分是可选的),方法与属性是一个或两个方法的组合相同。
AddHandler
和RemoveHandler
根本不修改方法。他们只是调用事件的“添加”和“删除”部分,这些部分是实现部分的一部分。
通常情况下,事件通过对具有适当委托类型的字段的引用来实现,其中Delegate.Combine
和Delegate.Remove
用于执行适当的操作。 (字段值将被更改 - 请记住,委托类型是不可变的。)引发事件仅包含调用委托。
至于为什么AddHandler
等是单独的语句类型 - 如果它们是方法,参数是什么?有些事情必须提及“事件”。基本上,AddHandler
语句对应于适当的事件“add”方法,就像属性获取对应于适当的属性“get”方法一样。你可以用反射做到这一点,通过EventInfo.AddHandler
。
请参阅我的article on delegates and events了解更多详情,这可能有所帮助 - 它来自C#背景,但其原理显然是相同的。
事件只是一个代表。下面是一些代码,工程就像一个普通的事件,使用委托对象,而不是玩:
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。就像替换它或将其设置回无。在大多数情况下,这是灾难性的,首先订阅事件的代码将停止正常工作。
事件 VB.NET中的关键字可以防止发生这种情况。它包装了委托对象,并使其他代码无法访问,而不是提供的关键字。与财产如何保护对领域的访问有些类似。 AddHandler和RemoveHandler确保现有注册不会消失。 RaiseEvent触发事件,不需要检查Nothing。
这是否意味着'RaiseEvent SomeEvent'和'SomeEvent()'具有相同的影响(其中'SomeEvent'被声明为'Public Event SomeEvent As Action')。在VS2010中使用'SomeEvent()'语法给我一个编译错误,我必须使用'RaiseEvent'语法。 – 2013-04-29 14:52:22
@ just.another.programmer:嗯,我相信如果你能够得到这个值,他们会有同样的效果,但是这是VB方面的一个细节,我不太熟悉。 – 2013-04-29 14:54:54