gpt4 book ai didi

vb.net - EventHandler与Delegate的误区

转载 作者:行者123 更新时间:2023-12-04 05:09:19 42 4
gpt4 key购买 nike

请看下面的代码,它按我的预期工作:

Partial Class _Default
Inherits System.Web.UI.Page


Delegate Sub TestEventHandler(ByVal o As Object, ByVal e As EventArgs)
Dim alhandler As TestEventHandler = AddressOf TestEventMethod
Public Event Test1 As TestEventHandler
Public Event Test2 As TestEventHandler

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
AddHandler Me.Test1, alhandler
AddHandler Me.Test2, alhandler
RaiseEvent Test1(Me, e)
RaiseEvent Test2(Me, e)
RemoveHandler Me.Test1, alhandler
RaiseEvent Test1(Me, e)
End Sub

Public Sub TestEventMethod(ByVal o As Object, ByVal e As EventArgs)
MsgBox("Test")
End Sub


End Class

我对以下两个陈述感到困惑:
Dim alhandler As TestEventHandler = AddressOf TestEventMethod '1
Public Event Test1 As TestEventHandler '2

1) This is saying that the reference of alHandler is a delegate that points to the address of a function. 2) This is saying that Test1 is an event of type Delegate. How can an event and a handler be a delegate?

最佳答案

正如其他人所说,每种类型的委托(delegate)都是一种类型,就像它是一个常规类一样。因此,在您的示例代码中,TestEventHandler是委托(delegate)类型。一个 TestEventHandler变量可以引用任何 TestEventHandler对象,就像任何其他变量可以引用它自己类型的任何对象一样。 TestEventHandler对象必须被实例化,就像任何其他类型的对象一样。

然而,委托(delegate)是特殊的,因为您使用不同的特殊语法来声明它们。例如,如果您有以下方法:

Public Sub MyMethod(Text As String)
' ...
End Sub

您可以创建一个与该方法签名匹配的委托(delegate),如下所示:
Public Delegate Sub MyMethodDelegate(Text As String)

请记住,这样做只是定义了 MyMethodDelegate类型。这不会声明该类型的变量,也不会实例化该类型的对象。

然而,VB.NET 语法中有两件事经常引起很多困惑。首先,当你声明一个事件时,你可以使用两种不同的语法:
Public Event MyEvent As MyMethodDelegate
Public Event MyEvent(Text As String)

这两行都做同样的事情。第一行使用已定义的委托(delegate)类型定义事件。第二行实质上是动态定义了一个新的未命名委托(delegate),然后将其用作事件的类型。 (注意,为了简单起见,我使用了 MyMethodDelegate,这会起作用,但标准规定事件应该有一个发送者和一个事件参数。)当一个事件被声明时,把它想象成一个变量。在幕后,它真的很像一个集合对象,它保存了使用 AddHandler 添加到其中的所有委托(delegate)对象的列表。功能。

VB.NET 中的第二个令人困惑的事情是,如果需要,当您使用 AddressOf 时,编译器会自动为您实例化一个新的委托(delegate)对象。功能。因此,例如,当您执行以下操作时:
AddHandler myObject.MyEvent, AddressOf MyMethod

它只是输入全文的快捷方式,如下所示:
AddHandler myObject.MyEvent, New MyMethodDelegate(AddressOf MyMethod)

后者,在我看来要清楚得多。您实际上在做的是创建该委托(delegate)类型的新对象并将该委托(delegate)对象指向该方法,然后将该委托(delegate)对象添加到事件(由对象类型定义的类似事件集合的变量)。

所以,在你的例子中,这一行:
Dim alhandler As TestEventHandler = AddressOf TestEventMethod

会更清楚地写成:
Dim alhandler As TestEventHandler = New TestEventHandler(AddressOf TestEventMethod)

它声明一个委托(delegate)变量,然后将其设置为指向该特定方法的新委托(delegate)对象。在这种情况下,它只是一个标准的委托(delegate)变量,而不是一个事件。事件与委托(delegate)字段/属性非常相似。事件本质上是一个围绕私有(private)委托(delegate)字段的访问器包装器,就像属性通常包装一个私有(private)字段一样。委托(delegate)字段和事件之间的最大区别在于事件支持 AddHandlerEventHandler函数和事件不能从定义它的类的外部引发/调用。

关于vb.net - EventHandler与Delegate的误区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15073327/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com