Microsoft & .NETVisual BasicPaul Kimmel on VB/VB.Net - May 31, 2001

Paul Kimmel on VB/VB.Net – May 31, 2001

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Array Enumeration in VB.NET, Part III

Last week I finished Part II of this series. Self-satisfied that I had cleverly demonstrated Enumerators, I finished the article and sent it to the editor. No sooner was it printed than someone wrote me to demonstrate the For Each loop. 

If you are just getting here, let me catch you up. All arrays in Visual Basic.NET are derivatives of System.Array, a class defined in the System namespace. Because all arrays are instances of System.Array classes, arrays can and do have members and capabilities surpassing VB6 arrays. An example of array methods is the GetLowerBound and GetUpperBound methods. Yes, you can still use LBound and UBound or an index to iterate over elements in an array, or, you can use the new GetLowerBound and GetUpperBound methods. As the reader mentioned you may also use a For Each loop. Assuming we have an array of integers in VB.NET, all of the following work as you might expect.

Dim Ints() As Integer = {0, 1, 2, 3, 4, 5}
Dim I As Integer
' Version 1
For I = 0 To 5
  Debug.WriteLine(Ints(I))
Next

' Version 2
Dim V As Object
For Each V In Ints
  Debug.WriteLine(V)
Next

' Version 3
For I = LBound(Ints) To UBound(Ints)
  Debug.WriteLine(Ints(I))
Next

' Version 4
For I = Ints.GetLowerBound(0) To Ints.GetUpperBound(0)
  Debug.WriteLine(Ints(I))
Next

Ints is defined to be an array of six elements, indexable from 0 to 5. (Index boundaries may vary depending on the beta version of .NET you are currently using. Version 1 will not work correctly in beta 1.) The first loop uses literal lower and upper bound indexes to write the elements to the Output Window. The second loop uses the For Each construct, substituting Object for Variant as required. The third loop shows the older LBound and UBound functions, and the fourth loop shows the new GetLowerBound and GetUpperBound methods. All four of these ways to iterate over the elements of an array are supported. Semantically the last one is the most correct because it demonstrates array self-awareness, which is more object-oriented. Version one is not very portable. Version 2 is okay but probably exists to support COM more than anything, and version 3 is portable but the array should know its own boundaries. 

In addition to the four versions of iterating an array already shown, there is a fifth way. The fifth way to iterate an array is to use enumerators as demonstrated last week. The fragment that follows demonstrates using the IEnumerator interface.

Dim Ints() As Integer = {0, 1, 2, 3, 4, 5}
Dim Enumerator As IEnumerator = Ints.GetEnumerator()

While (Enumerator.MoveNext())
  Debug.WriteLine(Enumerator.Current())
End While

The enumerator is a COM interface. The basic IEnumerator implements three methods: MoveNext(), Current(), and Reset(). 

There are several reasons we want to use enumerators. (First, I must caution you that the best improvements in object-oriented languages are small increments and often pretty simple.) Using enumerators allows us to use a consistent interface for enumerating many kinds of collections of data, including things like recordsets, bit-arrays, collections, and System.Array. The second reason enumerators are important is that enumerators are objects that can be passed as parameters to methods. You cannot pass a For Next or For Each loop, but you can pass an enumerator. Suppose we have a method PrintAll. By defining the method to take an IEnumerator we can pass any instance of an enumerator to the method and it behaves correctly in a polymorphic way. The example demonstrates the PrintAll behavior, writing the elements referred to by any Enumerator to the Output Window.

Private Sub PrintAll(ByVal Enumerator As IEnumerator)

  While (Enumerator.MoveNext())
    Debug.WriteLine(Enumerator.Current())
  End While

End Sub

Private Sub TestPrintAll()

  Dim Strings() As String = {"Some", "text"}
  PrintAll(Strings.GetEnumerator())

  Dim Ints() As Integer = {0, 1, 2, 3, 4, 5}
  PrintAll(Ints.GetEnumerator())

End Sub

PrintAll takes an IEnumerator and iterates over each element, writing the contents to the Output Window. TestPrintAll declares a couple of arrays and has PrintAll display the contents of each array passed.

Clearly the reader was correct: a For Each loop works in VB.NET. An important element of this fact is that data accessed through an enumerator is read only. The Current method returns the value of the element referenced by the internal mechanism of the enumerator, hence you will need to use another construct if you need to modify the elements of an array. Semantically, using the For Next loop with the GetLowerBound and GetUpperBound method invocation is probably the most appropriate. However, if you have a good reason for using any of the ways to enumerator elements of an array then by all means use them. Keep one caveat in mind: eventually older modus may be deprecated in future versions of
VB.NET.

About the Author

Paul Kimmel is a freelance writer for Developer.com and CodeGuru.com. He is the founder of Software Conceptions, Inc, found in 1990. Paul Kimmel is available to help you build Visual Basic.NET solutions. You may contact him at pkimmel@softconcepts.com.

# # #

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories