EventHandler和代表误会 [英] EventHandler and Delegate misunderstanding

查看:98
本文介绍了EventHandler和代表误会的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看下面的代码,这个代码可以像我想象的那样工作:

Please take a look at the code below, which works as I would expect:

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

我很困惑以下两个语句:

I am confused with the two statements below:

Dim alhandler As TestEventHandler = AddressOf TestEventMethod '1
Public Event Test1 As TestEventHandler '2




1)这就是说,alHandler的引用是
指向一个函数的地址。 2)这就是说Test1是
一个类型为Delegate的事件。事件和处理程序如何成为
委托?

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?


推荐答案

已经说过,每种类型的代表都是一种类型,就像它是一个普通的类一样。所以,在你的示例代码中, TestEventHandler 是一个委托类型。一个 TestEventHandler 变量可以引用任何 TestEventHandler 对象,就像任何其他变量都可以引用其自己类型的任何对象一样。 TestEventHandler 对象必须被实例化,就像任何其他类型的对象。

As others have said, each type of delegate is a type, just as if it were a regular class. So, in your example code, TestEventHandler is a delegate type. A TestEventHandler variable can reference any TestEventHandler object, just like any other variable can reference any object of its own type. TestEventHandler objects must be instantiated, just like objects of any other type.

代表是特别的,但是您声明它们使用不同的特殊语法。例如,如果您有以下方法:

Delegates are special, however, in that you declare them using a different, special, syntax. For instance, if you had the following method:

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

您可以创建一个与该方法签名相匹配的委托: p>

You could create a delegate that matches that method signature like this:

Public Delegate Sub MyMethodDelegate(Text As String)

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

Remember, by doing so, that simply defines the MyMethodDelegate type. That doesn't declare a variable of that type nor does it instantiate an object of that type.

然而,VB.NET语法中有两件事情,通常导致很多混乱。首先,当你声明一个事件时,你可以使用两种不同的语法:

There are two things in VB.NET syntax, however, which often cause a lot of confusion. First, when you declare an event, you can use two different syntax:

Public Event MyEvent As MyMethodDelegate
Public Event MyEvent(Text As String)

这两行都做同样的事情。第一行使用已定义的委托类型定义事件。第二行基本上定义了一个新的未命名的委托,然后将其用作事件的类型。 (注意,为了简单起见,我正在使用 MyMethodDelegate ,这样做将会起作用,但标准规定事件应该具有发件人和事件参数。 em>当一个事件被声明时,想像一个变量。在幕后,它真的像一个集合对象,使用 AddHandler 函数保存所有添加到其中的委托对象的列表。

Both of those lines do the same thing. The first line defines the event using an already defined delegate type. The second line essentially defines a new unnamed delegate on the fly and then uses it as the type for the event. (Note, I'm using the MyMethodDelegate for simplicity, and that will work, but standards dictate that events should have a sender and an event args.) When an event is declared, think of it like a variable. Behind the scenes, it's really like a collection object that keeps a list of all the delegate objects that are added to it using the AddHandler function.

VB.NET中的第二个令人困惑的是,编译器会自动为您实例化一个新的委托对象,如果需要,当您使用 AddressOf 功能。所以,例如,当你这样做:

The second confusing thing in VB.NET is that the compiler will automatically instantiate a new delegate object for you, if necessary, when you use the AddressOf function. So, for instance, when you do something like this:

AddHandler myObject.MyEvent, AddressOf MyMethod

这只是键入全文的快捷方式,如下所示:

It's just a shortcut for typing the full text, like this:

AddHandler myObject.MyEvent, New MyMethodDelegate(AddressOf MyMethod)

后者在我看来更为明确。您正在做的是创建该委托类型的新对象,并将该委托对象指向该方法,然后将该委托对象添加到事件(该对象类型定义的类似事件的类变量)。

The latter, in my opinion is much more clear. What you are actually doing is creating a new object of that delegate type and pointing that delegate object to that method, and then adding that delegate object to the event (that event collection-like variable defined by the object's type).

所以,在你的例子中,这一行:

So, in your example, this line:

Dim alhandler As TestEventHandler = AddressOf TestEventMethod

将更清楚地写为:

Dim alhandler As TestEventHandler = New TestEventHandler(AddressOf TestEventMethod)

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

It's declaring a delegate variable and then setting it to a new delegate object that points to that particular method. In this case, it's just a standard delegate variable, not an event. Events are very similar to delegates field/properties. Events are essentially an accessor wrapper around a private delegate field, in the same way that properties often wrap a private field. The big differences between delegate fields and events are that events support the AddHandler and EventHandler functions and events cannot be raised/invoked from outside of the class that defines it.

这篇关于EventHandler和代表误会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆