屬性訪問器的可訪問性
以前,一個一直困擾我的問題就是Visual Basic .NET中Get和Set訪問器必須具有相同的可訪問性(Public、Friend、或Private)。如果你想創建一個只讀的Public屬性(只有Get被公開),那麼在你的組件中並沒有Set訪問器來強制確認或者自定義屬性的處理。
現在,Visual Basic 2005中的Get和Set訪問器可以設置不同的可訪問性了,只是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
當客戶端爲你的事件添加或刪除了一個處理器後,AddHandler或RemoveHandler歷程開始運作。而當事件被引發後,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.