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