【问题标题】:How are events implemented事件是如何实现的
【发布时间】:2013-04-29 14:27:26
【问题描述】:

我专门询问 VB.NET,但我想其他语言的一般原则是相同的。我认为事件是 .NET 中的一流概念,但从reflection 看来,它只是一个在引发事件时调用的特定方法

  1. AddHandlerRemoveHandler 如何动态地修改方法(AFAIK,事件早于DynamicMethods?
  2. RaiseEvent如何调用方法?
  3. 为什么AddHandlerRemoveHandlerRaiseEvent 实现为语句而不是方法

【问题讨论】:

    标签: .net events implementation


    【解决方案1】:

    不,事件只是两个或三个方法的组合(“raise”部分是可选的),就像属性是一个或两个方法的组合一样。

    AddHandlerRemoveHandler 根本不修改方法。他们只是调用事件的“添加”和“删除”部分,这些部分负责实现部分。

    通常,事件是通过对具有适当委托类型的字段的引用来实现的,Delegate.CombineDelegate.Remove 用于执行适当的操作。 (字段值将被更改 - 请记住委托类型是不可变的。)引发事件仅包括调用委托。

    至于为什么AddHandler等是单独的语句类型——如果它们是方法,参数会是什么?有些东西必须提到“事件”。基本上,AddHandler 语句对应于适当的事件“add”方法,就像属性获取对应于适当的属性“get”方法一样。您可以通过EventInfo.AddHandler 进行反射。

    请参阅我的article on delegates and events 了解更多可能有帮助的详细信息 - 它来自 C# 背景,但原理显然是相同的。

    【讨论】:

    • 这是否意味着RaiseEvent SomeEventSomeEvent() 具有相同的影响(其中SomeEvent 被声明为Public Event SomeEvent As Action)。在 VS2010 中使用 SomeEvent() 语法会给我一个编译错误,我必须使用 RaiseEvent 语法。
    • @just.another.programmer:嗯,我相信如果你可以获得相同的效果,是的 :) 但这是 VB 的一个细节事情的另一面,我不太熟悉。
    【解决方案2】:

    事件只是一个委托。这里有一些代码可以像常规事件一样使用,而是使用委托对象:

    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 中的Event 关键字可以防止这种情况发生。它包装了委托对象,使其无法被其他代码访问,超出了提供的关键字。有点类似于属性如何保护对字段的访问。 AddHandler 和 RemoveHandler 确保现有注册不会消失。 RaiseEvent 无需 Nothing 检查即可触发事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 2015-12-10
      • 1970-01-01
      • 2011-12-19
      • 2010-12-22
      • 1970-01-01
      相关资源
      最近更新 更多