友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
VB2008从入门到精通(PDF格式英文版)-第45部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
internal array。 This class manages the problem of increasing the size of an array。
o Hashtable: A collection class where the individual objects are stored using key/value
pairs。 In the previous chapter; the indexer was used to retrieve a room grouping based
on its identifier。 You could use a Hashtable to acplish the same thing。
o ICollection: An interface implement by ArrayList that provides basic functionality that
copies the references to another array。
o IDictionary: An interface implemented by Hashtable that allows a programmer to asso
ciate a key with a value。
o IList: An interface implemented by ArrayList that provides a general…access mechanism
for manipulating a collection of items。
o Queue: A collection that implements the first in; first out (FIFO) mechanism。 You could
use a queue when you are processing a set of instructions。 The first instruction to process
would be the first instruction added to the collection。
o Stack: A collection that implements the last in; first out (LIFO) mechanism。 Think of it as
a stack of papers。 When one piece of paper is laid on top of another; the first piece of
paper that is processed is the last piece of paper added to the stack of papers。
All of the collection types—ArrayList; Hashtable; Queue; and Stack—implement a way to
store a set of types。 The difference in the collection types lies in how the individual objects are
stored and retrieved from the collection。 For examples of using these collection types; see the
“Learning More About Collection Types” section later in this chapter。
Let’s walk through an example of using these collection classes。 Begin by creating a console
application and call it OneToManySamples。 Then add a new class (right…click your console appli
cation project and select Add Class)。 Call it Example。vb and add all of the following code to it:
Class Example
Public Property Value() As Integer
Get
Return _value
End Get
Set(ByVal value As Integer)
_value = value
End Set
End Property
Private _value As Integer
End Class
Friend Module Tests
Private Sub PlainVanillaObjects()
Dim objects As IList = New ArrayList()
…………………………………………………………Page 253……………………………………………………………
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 231
objects。Add(New Example With {。Value = 10})
objects。Add(New Example With {。Value = 20})
For Each obj As Example In objects
Console。WriteLine(〃Object value (〃 & obj。Value & 〃)〃)
Next
End Sub
Public Sub RunAll()
PlainVanillaObjects()
End Sub
End Module
This is the type of code written before Visual Basic 2005; and it follows a standard set of steps:
1。 You define a custom type ( Example in this example)。
2。 You instantiate the custom type and add the instances to a collection。 In the example;
two instances of Example are added to the collection type ArrayList。
3。 The collection is manipulated to allow you to access and manipulate the instances of
the custom types。 In the example; the collection ArrayList is an interface instance of IList。
The bolded code in the example is where the action takes place。 Instantiating the type
ArrayList is the instantiation of a collection manager。 The ArrayList instance is then assigned
to the variable objects; which is of type IList。 IList is an interface making it possible to use the
collection in the context of a ponent…oriented development environment。 To add two objects
to the collection; we call the Add() method twice。 To iterate the elements in the collection; we
use the For Each statement。
■Note The fact that the collection classes can be used in the context of a ponent…oriented application
is no coincidence。 When Microsoft created its library; ponents were an essential part of the library。
To run the tests; open Module1。vb in your console application and edit it as follows:
Module Module1
Sub Main()
BeforeVisualBasic8。Tests。RunAll()
Console。ReadKey()
End Sub
End Module
Press Ctrl+F5 to run the application and see the results。
■Note We did not need to import the System。Collections namespace because it is imported by default
in Visual Basic 2008。
…………………………………………………………Page 254……………………………………………………………
232 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
The Problem of Mixed Types
What is unique about the sample code is that the For Each statement works and happens to
know that the objects in the collection are of type Example。 However; the following code adds a
different object to the collection; which will cause the iteration to fail。
Class Another
End Class
Dim objects As IList = New ArrayList()
objects。Add(New Example With {。Value = 10})
objects。Add(New Example With {。Value = 20})
objects。Add(New Another())
For Each obj As Example In objects
Console。WriteLine(〃Object value (〃 & obj。Value & 〃)〃)
Next
The bolded code illustrates how the collection object contains two instances of Example
and one instance of Another。 The code will pile; which misleads you into believing every
thing is fine。 If you try to run the application (either normally or in debug mode); you will see
something similar to the following:
Unable to cast object of type 'OneToManySamples。Another' to type
'OneToManySamples。Example'。
So; should a collection contain multiple types? There are arguments for and against the
idea; but the problem is not the ability to mix types。 The problem is that you can mix types;
even if you don’t really intend to do that。
Using the For Each statement with mixed types will result in an exception; because for
each iteration; the object in the collection is cast to a type Example。 As the last item in the collec
tion is of type Another; the cast will fail; and an exception will be generated。 Collections before
2。0 could not enforce type consistency; and that was a problem。
Had you desired to mix types; the proper For Each loop would have been as follows:
Dim objects As IList = new ArrayList()
objects。Add(New Example With {。Value = 10})
objects。Add(New Example With {。Value = 20})
objects。Add(New Another())
For Each obj As Object In objects
If TypeOf (obj) Is Example Then
Dim example As Example = CType(obj; Example)
Console。WriteLine(〃Object value (〃 & example。Value & 〃)〃)
ElseIf TypeOf (obj) Is Another Then
Console。WriteLine(〃This is another object〃)
End If
Next
…………………………………………………………Page 255……………………………………………………………
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 233
The Problem of Value Types
Another issue with pre…Visual Basic 2005 collections is that they have performance problems。
Consider the following code that manipulates value types。
Dim objects As IList = New ArrayList()
objects。Add(1)
objects。Add(2)
For Each val as Integer in objects
Console。WriteLine(〃Value (〃 & val & 〃)〃)
Next
In the example; an ArrayList is again instantiated; but this time; the numbers 1 and 2 are
added to the collection。 Then; in the For Each statement; the integers are iterated。 The code
works; but there is a hidden performance hit。 The items added to the collection are value types;
which means you are manipulating stack…based memory。
However; the definition of IList uses objects:
Public Interface IIList
Inherits ICollection; IEnumerable
' Methods
Function Add(ByVal value As Object) As Integer
Sub Clear()
Function Contains(ByVal value As Object) As Boolean
Function IndexOf(ByVal value As Object) As Integer
Sub Insert(ByVal index As Integer; ByVal value As Object)
Sub Remove(ByVal value As Object)
Sub RemoveAt(ByVal index As Integer)
' Properties
ReadOnly Property IsFixedSize() As Boolean
ReadOnly Property IsReadOnly() As Boolean
Property Item(ByVal index As Integer) As Object
End Interface
How IList is defined and how a value type is defined should raise alarms。 An object is a
reference type; and thus you have a conflict: IList stores reference types; but Integer is a value
type。
What’s happening is that the environment knows that there is a conflict and adds a
fix。 Don’t think of the fix as a hack; but as a way of solving a problem that all virtual machine
environments like need to address。 The environment uses the terms boxing and
unboxing to denote converting a value type into a reference type and then back again; respectively。
To understand boxing and unboxing; let’s consider the context。 You are creating a list that
references value types。 The array is a reference type that is stored on the heap; but value types are
stored on the stack。 If you get the array to reference data on the stack; you will have a consistency
issue; since the stack changes。 Thus; you will need to move the memory from the stack to the
heap; but that would violate the principle behind value types。 The solution is the promise
of boxing and unboxing。
…………………………………………………………Page 256……………………………………………………………
234 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
To illustrate what boxing does; I have written some code that is similar to the boxing of a
value type。 The difference is that my code is explicit and boxing is done automatically。
Class ReferenceHeap
Public Value As Integer
End Class
。 。 。
Public Sub Method()
Dim onStack As Integer = 1
Dim onHeap As ReferenceHeap = New ReferenceHeap() With { 。Value = onStack }
End Sub
In the example; Method() declares a value…type variable named onStack; which is allocated
in the context of a method and is thus on the stack。 The type ReferenceHeap is a class; and thus
a reference type; and automatically all of its data is stored on the heap。 When the variable
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
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!