按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
End Function
Public Sub Reset() _
Implements IEnumerator。Reset
_currNode = _firstNode
End Sub
End Class
A class that can be enumerated must fulfill two objectives: implement the IEnumerable
interface and implement the IEnumerator interface。 The IEnumerable class has a single method;
GetEnumerator(); which is used to retrieve a class instance that implements the IEnumerator
interface。 The two interfaces are split because retrieving the iteration functionality and iter
ating the collection are two separate steps。 However; in the case of LinkedListEnumerable;
these steps are bined into one class; and that is often the case。
The best way to explain how LinkedListEnumerable works is to go through the code and
explain what methods and properties are called。
1。 The code in the client application starts a For Each loop; and sets up a context where a
collection of elements is being iterated。
2。 The code calls the collection iterator。 In the example; this means calling the method
RoomGroupingIterator()。
3。 RoomGroupingIterator() returns an instance of LinkedListEnumerable; which is assigned
the linked list that will be iterated。
Public Function RoomGroupingIterator() As IEnumerable
Return New LinkedListEnumerable(_roomGroupings)
End Function
…………………………………………………………Page 241……………………………………………………………
C H AP TE R 8 ■ L E AR N IN G AB O U T CO M P O N E N T O R IE N TE D A R CH I TE C TU R E 219
4。 The method LinkedListEnumerable。GetEnumerator() is called; and an instance of
IEnumerator is returned。
5。 The code calls the method LinkedListEnumerable。MoveNext()。
6。 The implementation of MoveNext() returns True to indicate that it was possible to move
to the next element。 If False is returned; it means that the end of the collection—or in
this case; the linked list—is reached。
7。 If MoveNext() returns True; then the property LinkedListEnumerable。Current() is called
to retrieve the current linked list element。
8。 The retrieved linked list element is assigned to the variable of the For Each loop; which
is rg in this example。
9。 Control is returned to the For Each loop; and the user code does something with the
linked list element。
10。 When the For Each loop attempts another iteration; steps 5 through 9 are repeated until
MoveNext() returns False。
11。 When MoveNext() returns False; the iterator exits; causing an exit of the For Each loop。
Adding Rooms to Groupings
The data handle that we defined when adding the grouping is used when we add a room to a
grouping。 The idea of the handle is to provide a reference that the kernel can use。 Since the
handle is an instance of a RoomGrouping type; whenever a room is added to a grouping based on
a handle; it is not necessary to find the room grouping。 The handle is the room grouping; and
all that is necessary is a type cast。 The following demonstrates how to add a room to a room
grouping (in LightingController)。
Public Sub AddRoomToGrouping(ByVal grouping As Object; ByVal room As IRoom)
Dim roomGrouping As RoomGrouping = TryCast(grouping; RoomGrouping)
If roomGrouping Is Nothing Then
Throw New Exception( _
〃Handle grouping is not a valid room grouping instance〃)
End If
Dim oldRooms As Room = TryCast(roomGrouping。Rooms; Room)
If oldRooms Is Nothing Then
roomGrouping。Rooms = New Room() With {。ObjRoom = room}
Else
roomGrouping。Rooms。Insert(New Room() With {。ObjRoom = room})
End If
End Sub
In the implementation of AddRoomToGrouping(); the first step is to cast the handle grouping
to an instance of RoomGrouping。 The cast used is the TryCast() function; so that if the cast fails;
it is only necessary to test if roomGrouping is not Nothing。 Executing the Nothing test is absolutely
vital; otherwise; you might perform operations that will cause an exception to be thrown。
…………………………………………………………Page 242……………………………………………………………
220 CH AP T E R 8 ■ L E A R N IN G AB OU T CO M P O N E N TO R IE N T E D AR C HI TE CT U R E
Once the handle has been cast to a RoomGrouping instance; adding a room to the linked list
is trivial。 Adding a room involves only assigning the head of the list if there are no rooms in the
list; or calling the method Insert() if there are rooms。
Performing Operations on a Group
With a grouping defined; you can perform global operations that affect all rooms of a grouping。
One example is turning off the lights in all the rooms in a grouping; which is based on the IRoom
interface instance。 Here is the code to turn off all of the lights in a grouping:
Public Sub TurnOffLights(ByVal grouping As Object)
Dim enumerableGrouping As LinkedListEnumerable = _
New LinkedListEnumerable(TryCast(grouping; BaseLinkedListItem))
For Each room As IRoom In enumerableGrouping
Dim remote As IRemoteControlRoom = TryCast(room; IRemoteControlRoom)
Dim sensorRoom As ISensorRoom = TryCast(room; ISensorRoom)
If sensorRoom IsNot Nothing Then
If Not sensorRoom。IsPersonInRoom Then
Continue For
End If
ElseIf remote Is