[译]Visual Basic 2005在语言上的增强(八)属性访问器的可访问性和自定义事件访问器

类别:.NET开发 点击:0 评论:0 推荐:

属性访问器的可访问性

以前,一个一直困扰我的问题就是Visual Basic .NET中GetSet访问器必须具有相同的可访问性(Public、Friend、或Private)。如果你想创建一个只读的Public属性(只有Get被公开),那么在你的组件中并没有Set访问器来强制确认或者自定义属性的处理。

现在,Visual Basic 2005中的GetSet访问器可以设置不同的可访问性了,只是Set在访问上必须比Get更受限制:
Private _myProp As String

Public Property MyProp() As String

    Get
        Return _myProp
    End Get

    Friend Set(ByVal value As String)
        If value.Trim.Length > 0 Then
            _myProp = value.Trim
        Else
            value = "<no value>"
        End If
    End Set

End Property

无论是对于团队开发环境还是对于为了努力追求代码最大重用率的个人开发者,这个特性都相当有用。

自定义事件访问器

事件访问器允许你定义一个自定义事件,并且,你可以控制在当客户端添加或删除了事件处理器并引发你的事件后所发生的情况。假设你有一个自定义的类,在该类中你引发了一个RateChanged事件。你可以按照下面两种方式其中一种来声明普通的事件:
Public Event RateChanged()
'或者
Public Event HoursChanged As EventHandler

用这种方式声明事件会产生一个自动托管的备份存储。换言之,系统将处理事件托管和分派的方式。通常情况下这就很好了,但是有时候,你需要对如何通知事件监听器的方式拥有更多的控制。

你可以利用这个新的Custom关键字来定义一个自定义事件以及它的访问修饰符。当你在事件声明上敲下回车键后,Visual Basic 2005将为你自动生成代码原形,其生成方式就像Property访问器那样:
Public Custom Event NameChanged As EventHandler
   
    AddHandler(ByVal value As EventHandler)
        '把处理器与备份存储挂钩
    End AddHandler

    RemoveHandler(ByVal value As EventHandler)
        '从备份存储中删除处理器
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
        '激发监听器
    End RaiseEvent

End Event

当客户端为你的事件添加或删除了一个处理器后,AddHandlerRemoveHandler历程开始运作。而当事件被引发后,RaiseEvent历程开始执行。通过这种方式,你可以按照你想要为事件托管备份存储的方式来采取特别的操作。当你用这种方式创建了这些自定义事件,你就可以把该事件当作属性来看待。

一个展示了自定义事件访问器有用一面的例子,就是当你的对象是可序列化的、并且你有一个可以被一个不可序列化的委托对象处理的事件的时候。如果你试图通过一个普通事件来序列化你的对象,序列化就会失败,这是因为备份该事件的存储是不可序列化的。Rocky Lhotka(另一个Visual Basic MVP)对其中的作用方式作了解释,还给出了一个详细的例子,你可以去参看他的blog:http://www.lhotka.net/WeBlog/CommentView.aspx?guid=776f44e8-aaec-4845-b649-e0d840e6de2c。


@以下是原文供参考@

Property Accessor Accessibility

An issue that has always bothered me about Visual Basic .NET properties is that the Get and Set accessors must have the same accessibility (Public, Friend, or Private). If you want to create a read-only public property (only the Get is public), there is no Set accessor you can use within your component to enforce validation or custom property handling.

The Get and Set accessors in Visual Basic 2005 can now have different accessibility settings, as long as Set is more restrictive than Get:
Private _myProp As String

Public Property MyProp() As String

    Get
        Return _myProp
    End Get

    Friend Set(ByVal value As String)
        If value.Trim.Length > 0 Then
            _myProp = value.Trim
        Else
            value = "<no value>"
        End If
    End Set

End Property

This is especially helpful in team development environments and for individual developers striving to get the highest amount of reuse out of their code.

Custom Event Accessors

Event accessors let you define a custom event and control what happens as clients add and remove handlers and raise your event. Suppose you have a custom class in which you raise an event RateChanged. You declare normal events in one of two ways:
Public Event RateChanged()
'or
Public Event HoursChanged As EventHandler

Events declared in this way have an automatically managed backing store. In other words, the system handles how the event is managed and dispatched. Normally this is fine, but sometimes you need more control over how the event's listeners are notified.

You declare a custom event and its accessors using the new Custom keyword. When you hit the enter key on the event declaration, Visual Basic 2005 creates the code prototype for you in the same way Property accessors are generated:
Public Custom Event NameChanged As EventHandler
   
    AddHandler(ByVal value As EventHandler)
        'hook handler to backing store
    End AddHandler

    RemoveHandler(ByVal value As EventHandler)
        'remove handler from backing store
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
        'invoke listeners
    End RaiseEvent

End Event

When the client adds or removes a handler for your event, the AddHandler or RemoveHandler routine runs. When the event is raised, the RaiseEvent routine executes. In this way, you can take specific actions based on how you want to manage the backing store for the event. When you create custom events this way, you can think of the event as if it were a property.

An example where this is useful is when your object is serializable and you have an event that is handled by a non-serializable delegate object. If you try to serialize your object with a normal event, serialization will fail because the storage backing the event isn't serializable. Rocky Lhotka (another Visual Basic MVP) has an explanation of how this works and a detailed example in his blog entry at http://www.lhotka.net/WeBlog/CommentView.aspx?guid=776f44e8-aaec-4845-b649-e0d840e6de2c.

本文地址:http://com.8s8s.com/it/it42151.htm