按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
onHeap is allocated and initialized; the value from onStack is copied to the heap and assigned to
the instance onHeap。 This is what boxing does; except Visual Basic does it automatically and
transparently。
■Note It is important to remember that when you box and unbox; you are copying values back and forth
between the stack and the heap。 Thus; if the variable onStack is changed; the value of onHeap does not change。
Unboxing refers to copying the value from the heap to the stack; which in the case of the
example; means transferring the value from the variable onHeap to onStack。
Boxing/unboxing happens automatically; but it has a performance penalty; since memory
is allocated and assigned。
Managing a Collection After Visual Basic 2005
The two problems of storing mixed object types and the performance penalty of boxing/unboxing
required Microsoft to carefully consider a solution。 After much debate and thinking; Microsoft
introduced generics。 In a nutshell; generics solve both collection problems by enforcing
a type。 ( generics solve broader problems as well。)
Collections are an ideal application of generics because collections are utilitarian。
You don’t use collections to solve the problem of calculating taxes。 You use collections to solve
the problem of how to create a collection of ines and a collection of deductions。
Here is an example of how to use generics…based collections (they are in the System。
Collections。Generic namespace; which we also do not need to import):
Dim lst As IList(Of Example) = New List(Of Example)()
lst。Add(New Example() With { 。Value = 10 })
lst。Add(New Example() With { 。Value = 20 })
For Each item As Example In lst
Console。WriteLine(〃item (〃 & item。Value & 〃)〃)
Next
…………………………………………………………Page 257……………………………………………………………
C HA P TE R 9 ■ L E AR N I N G A B O U T L I ST S; DE L E G AT E S ; AN D L A M B D A E X PR E SSI O N S 235
The bolded line represents the generics…based code。 The code used to add an object
and the For Each loop are identical to that used in the pre…Visual Basic 2005 example。
Between the brackets in the type declaration and after the Of keyword is an identifier that
is the specialization of the general approach。 Whatever is inside the brackets when you declare
an IList or List is saying; “I want my collection to contain instances of the type defined inside
the brackets。” You cannot add any objects that are not related to the type defined in IList or
List; so the following code would not pile。
lst。Add(New Another())
This is because the generics collection is type…safe and does not allow mixed types。
It allows only objects of type Example。
When you declare a list like this:
Dim lst As IList(Of Example)
you are saying that the list has a method declared like this:
Sub Add(ByVal item As Example)
If you are programming with Visual Basic 2008; you should use Visual Basic 2005 and later
collection classes。 The non… generics collection classes are; to a large degree; legacy code。
Whenever possible; use generics…based collection classes。
Now that you know how to manage a collection of objects; the next section will present a
mon collection…related problem and then solve the problem。
Adding Numbers and Finding Maximum Values
Let’s start out with a mon problem: addition of all elements in a collection。 Consider the
following code。
Dim elements As IList(Of Integer) = New List(Of Integer)()
elements。Add(1)
elements。Add(2)
elements。Add(3)
Dim runningTotal = 0
For Each value As Integer In elements
runningTotal = runningTotal + value
Next
This code has three parts: initialization of elements; adding of numbers to elements; and
iteration of all values in elements that are added to the variable runningTotal。 The code seems
acceptable。 But let’s say that you need to write another piece of code where; instead of calcu
lating the running total; you want to find the maximum value; like this:
…………………………………………………………Page 258……………………………………………………………
236 CH AP T E R 9 ■ L E A R N IN G AB OU T L I ST S; D E L E G A T E S; A N D L A M B DA E X P R E S SI ON S
Dim elements As IList(Of Integer) = New List(Of Integer)()
elements。Add(1)
elements。Add(2)
elements。Add(3)
Dim maxValue As Integer = Integer。MinValue
For Each value As Integer In elements
If value 》 maxValue Then
maxValue = value
End If
Next
The difference between the two code pieces is the bolded code。 The inner loop is different;
which is a potential problem。 In separate code files; the repetition is not apparent; but what if
you wanted to bine the code bases? The following code adds all elements and finds the
maximum value。
Dim elements As IList(Of Integer) = New List(Of Integer)()
elements。Add(1)
elements。Add(2)
elements。Add(3)
Dim runningTotal As Integer = 0
For Each value As Integer In elements
runningTotal = runningTotal + value
Next
Console。WriteLine(〃RunningTotal (〃 & runningTotal & 〃)〃)
Dim maxValue As Integer = Integer。MinValue
For Each value As Integer In elements
If value 》 maxValue Then
maxValue = value
End If
Next
Console。WriteLine(〃Maximum value is (〃 & maxValue & 〃)〃)
Another variation is as follows:
Dim elements As IList(Of Integer) = New List(Of Integer)()
elements。Add(1)
elements。Add(2)
elements。Add(3)
Dim runningTotal As Integer = 0
Dim maxValue As Integer = Integer。MinValue
For Each value As Integer In elements
If value 》 maxValue Then
maxValue = value
End If
runningTotal = runningTotal + value
Next
…………………………………………………………Page 259……………………………………………………………
C HA P TE R 9 ■ L E AR N I N G A B O U T L I ST S; DE L E G AT E S ; AN D L A M B D A E X PR E SSI O N S 237
For one or two instances; writing the For Each loop is not that problematic; but it would be
if you needed to use the iterator code in a dozen places。 This type of code is harder to maintain
and extend。 One way of being more efficient is to delegate the code to an abstract base class
that is implemented to calculate the running total or maximum value。 The following is the
plete code (you can place the three classes in separate files called IteratorBaseClass。vb;
RunningTotal。vb; and MaximumValue。vb if you want to test this)。
MustInherit Class IteratorBaseClass
Protected Sub New(ByVal collection As IList(Of Integer))
_collection = collection
End Sub
Public Function Iterate() As IteratorBaseClass
Dim element As Integer
For Each element In Me。_collection
ProcessElement(element)
Next
Return Me
End Function
Protected MustOverride Sub ProcessElement(ByVal value As Integer)
Private _collection As IList(Of Integer)
End Class
Class RunningTotal
Inherits IteratorBa