属性访问器的可访问性
以前,一个一直困扰我的问题就是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 = "
1<no value="">"
2End If
3End Set
4
5End Property
6
7无论是对于团队开发环境还是对于为了努力追求代码最大重用率的个人开发者,这个特性都相当有用。
8
9自定义事件访问器
10
11事件访问器允许你定义一个自定义事件,并且,你可以控制在当客户端添加或删除了事件处理器并引发你的事件后所发生的情况。假设你有一个自定义的类,在该类中你引发了一个 **RateChanged** 事件。你可以按照下面两种方式其中一种来声明普通的事件:
12Public Event RateChanged()
13'或者
14Public Event HoursChanged As EventHandler
15
16用这种方式声明事件会产生一个自动托管的备份存储。换言之,系统将处理事件托管和分派的方式。通常情况下这就很好了,但是有时候,你需要对如何通知事件监听器的方式拥有更多的控制。
17
18你可以利用这个新的 **Custom** 关键字来定义一个自定义事件以及它的访问修饰符。当你在事件声明上敲下回车键后,Visual Basic 2005将为你自动生成代码原形,其生成方式就像 **Property** 访问器那样:
19Public Custom Event NameChanged As EventHandler
20
21AddHandler ( ByVal value As EventHandler)
22'把处理器与备份存储挂钩
23End AddHandler
24
25RemoveHandler ( ByVal value As EventHandler)
26'从备份存储中删除处理器
27End RemoveHandler
28
29RaiseEvent ( ByVal sender As Object , ByVal e As EventArgs)
30'激发监听器
31End RaiseEvent
32
33End Event
34
35当客户端为你的事件添加或删除了一个处理器后, **AddHandler** 或 **RemoveHandler** 历程开始运作。而当事件被引发后, **RaiseEvent** 历程开始执行。通过这种方式,你可以按照你想要为事件托管备份存储的方式来采取特别的操作。当你用这种方式创建了这些自定义事件,你就可以把该事件当作属性来看待。
36
37一个展示了自定义事件访问器有用一面的例子,就是当你的对象是可序列化的、并且你有一个可以被一个不可序列化的委托对象处理的事件的时候。如果你试图通过一个普通事件来序列化你的对象,序列化就会失败,这是因为备份该事件的存储是不可序列化的。Rocky Lhotka(另一个Visual Basic MVP)对其中的作用方式作了解释,还给出了一个详细的例子,你可以去参看他的blog: http://www.lhotka.net/WeBlog/CommentView.aspx?guid=776f44e8-aaec-4845-b649-e0d840e6de2c 。
38
39
40**@以下是原文供参考@**
41
42Property Accessor Accessibility
43
44An 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.
45
46The **Get** and **Set** accessors in Visual Basic 2005 can now have different accessibility settings, as long as **Set** is more restrictive than **Get** :
47Private _myProp As String
48
49Public Property MyProp() As String
50
51Get
52Return _myProp
53End Get
54
55Friend Set ( ByVal value As String )
56If value.Trim.Length > 0 Then
57_myProp = value.Trim
58Else
59value = "<no value="">"
60End If
61End Set
62
63End Property
64
65This is especially helpful in team development environments and for individual developers striving to get the highest amount of reuse out of their code.
66
67Custom Event Accessors
68
69Event 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:
70Public Event RateChanged()
71'or
72Public Event HoursChanged As EventHandler
73
74Events 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.
75
76You 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:
77Public Custom Event NameChanged As EventHandler
78
79AddHandler ( ByVal value As EventHandler)
80'hook handler to backing store
81End AddHandler
82
83RemoveHandler ( ByVal value As EventHandler)
84'remove handler from backing store
85End RemoveHandler
86
87RaiseEvent ( ByVal sender As Object , ByVal e As EventArgs)
88'invoke listeners
89End RaiseEvent
90
91End Event
92
93When 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.
94
95An 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 .</no></no>