Arrays

It is possible to declare any type as an array of that type. Because an array is a modifier of another type, the basic Array class is never explicitly declared for a variable's type. The System.Array class that serves as the base for all arrays is defined such that it cannot be created, but must be inherited. As a result, to create an Integer array, a set of parentheses is added to the declaration of the variable. These parentheses indicate that the system should create an array of the type specified. The parentheses used in the declaration may be empty or may contain the size of the array. An array can be defined as having a single dimension using a single index, or as having multiple dimensions by using multiple indices.

All arrays and collections in .NET start with an index of zero. However, the way an array is declared in Visual Basic varies slightly from other .NET languages such as C#. Back when the first .NET version of Visual Basic was announced, it was also announced that arrays would always begin at 0 and that they would be defined based on the number of elements in the array. In other words, Visual Basic would work the same way as the other initial .NET languages. However, in older versions of Visual Basic, it is possible to specify that an array should start at 1 by default. This meant that a lot of existing code didn't define arrays the same way.

To resolve this issue, the engineers at Microsoft decided on a compromise: All arrays in .NET begin at 0, but when an array is declared in Visual Basic, the index defines the upper limit of the array, not the number of elements. The challenge is to remember that all subscripts go from 0 to the upper bound, meaning that each array contains one more element than its upper bound.

The main result of this upper-limit declaration is that arrays defined in Visual Basic have one more entry by definition than those defined with other .NET languages. Note that it's still possible to declare an array in Visual Basic and reference it in C# or another .NET language. The following code examples illustrate five different ways to create arrays, beginning with a simple integer array as the basis for the comparison:

Dim arrMyIntArray1(20) as Integer

In the first case, the code defines an array of integers that spans from arrMyIntArray1(0) to arrMyIntArray1(20). This is a 21-element array, because all arrays start at 0 and end with the value defined in the declaration as the upper bound.

Here is the second statement:

Dim arrMyIntArray2() as Integer = {1, 2, 3, 4}

The preceding statement creates an array with four elements numbered 0 through 3, containing the values 1 to 4.

In addition to creating arrays in one dimension it is possible to create arrays that account for multiple dimensions. Think of this as an array of arrays—where all of the contents are of the same type. Thus, in the third statement, you see an array of integers with two dimensions, a common representation of this is a grid:

Dim arrMyIntArray3(4,2) as Integer

The preceding declaration creates a multidimensional array containing five elements at the first level (or dimension). However, the second number 2 indicates that these five elements actually reference arrays of integers. In this case the second dimension for each of the first-level dimensions contains three elements. Visual Basic provides this syntax as shorthand for consistently accessing these contained arrays. Thus, for each of the items in the first dimensions, you can access a second set of elements each containing three integers.

The fourth statement which follows shows an alternative way of creating a multidimensional array:

Dim arrMyIntArray4( , ) as Integer = _
    { {1, 2, 3},{4, 5, 6}, {7, 8, 9},{10, 11, 12},{13, 14, 15} }

The literal array declaration creates a multidimensional array with five elements in the first dimension, each containing an array of three integers. The resulting array has 15 elements, but with the subscripts 0 to 4 at the first level and 0 to 2 for each second-level dimension. An excellent way to think of this is as a grid or a table with five rows and three columns. In theory you can have any number of dimensions; however, while having three dimensions isn't too difficult to conceptualize, increasing numbers of dimensions in your arrays can significantly increase complexity, and you should look for a design that limits the number of dimensions.

The fifth example demonstrates that it is possible to simply declare a variable and indicate that the variable is an array, without specifying the number of elements in the array:

Dim arrMyIntArray5() as Integer

Note that the preceding declaration is not multidimensional, it is a single-dimension array, just omitting the details for the number of elements defined. Similarly, if instead of creating arrMyIntArray5 with predefined values the goal had been to declare a two-dimensional array placeholder, the declaration would have included a comma: arrMyIntArray5(,). The usefulness of this empty declaration statement will become clearer as you look at various examples for using the preceding set of array declarations.

Multidimensional Arrays

The definition of arrMyIntArray3 and arrMyIntArray4 are multidimensional arrays. In particular, the declaration of arrMyIntArray4 creates an array with 15 elements (five in the first dimension, each of which contains three integers) ranging from arrMyIntArray4(0,0) through arrMyIntArray4(2,1) to arrMyIntArray4(4,2). As with all elements of an array, when it is created without specific values, the value of each of these elements is created with the default value for that type. This case also demonstrates that the size of the different dimensions can vary. It is possible to nest deeper than two levels, but this should be done with care because such code is difficult to maintain.

For example, the value of arrMyIntArray4(0,1) is 2, while the value of arrMyIntArray4(3,2) is 12. The following code adds a method called SampleMD, which can be run from the ButtonTest_Click handler, and which returns the elements of this multidimensional array's contents (code file: form1.vb):

     Private Sub SampleMD()
         Dim arrMyIntArray4(,) As Integer =
           {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14, 15}}
         Dim intLoop1 As Integer
         Dim intLoop2 As Integer
         For intLoop1 = 0 To UBound(arrMyIntArray4)
             For intLoop2 = 0 To UBound(arrMyIntArray4, 2)
                 TextBoxOutput.Text +=
                      "{" & intLoop1 & ", " & intLoop2 & "} = " &
                       arrMyIntArray4(intLoop1, intLoop2).ToString & vbCrLf
             Next
         Next
     End Sub

When run in the Test window from Chapter 1, this results in the output shown in Figure 7.1. Note that Figure 7.1 is significantly simpler than what is in the code download. The code download includes additional samples, including an additional button which will be created later in this chapter. If you are working alongside the chapter with your own sample code, your result will be similar to what is seen in Figure 7.1.

Figure 7.1 Sample output

7.1

The UBound Function

Continuing to reference the arrays defined earlier, the declaration of arrMyIntArray2 actually defined an array that spans from arrMyIntArray2(0) to arrMyIntArray2(3). That's because when you declare an array by specifying the set of values, it still starts at 0. However, in this case you are not specifying the upper bound, but rather initializing the array with a set of values. If this set of values came from a database or other source, then the upper limit on the array might not be clear. To verify the upper bound of an array, a call can be made to the UBound function:

UBound(ArrMyIntArray2)

The preceding line of code retrieves the upper bound of the first dimension of the array and returns 3. However, as noted in the preceding section, you can specify an array with several different dimensions. Thus, this old-style method of retrieving the upper bound carries the potential for an error of omission. The better way to retrieve the upper bound is to use the GetUpperBound method on your array instance. With this call, you need to tell the array which dimension's upper-bound value you want, as shown here (also returning 3):

ArrMyIntArray2.GetUpperBound(0)

This is the preferred method of obtaining an array's upper bound, because it explicitly indicates which upper bound is wanted when using multidimensional arrays, and it follows a more object-oriented approach to working with your array

The UBound function has a companion called LBound. The LBound function computes the lower bound for a given array. However, as all arrays and collections in Visual Basic are zero-based, it doesn't have much value anymore.

The ReDim Statement

The following code considers the use of a declared but not instantiated array. Unlike an integer value, which has a default of 0, an array waits until a size is defined to allocate the memory it will use. The following example revisits the declaration of an array that has not yet been instantiated. If an attempt were made to assign a value to this array, it would trigger an exception.

Dim arrMyIntArray5() as Integer
’ The commented statement below would compile but would cause a runtime exception.
'arrMyIntArray5(0) = 1

The solution to this is to use the ReDim keyword. Although ReDim was part of Visual Basic 6.0, it has changed slightly. The first change is that code must first Dim an instance of the variable; it is not acceptable to declare an array using the ReDim statement. The second change is that code cannot change the number of dimensions in an array. For example, an array with three dimensions cannot grow to an array of four dimensions, nor can it be reduced to only two dimensions.

To further extend the example code associated with arrays, consider the following, which manipulates some of the arrays previously declared:

Dim arrMyIntArray3(4,2) as Integer
Dim arrMyIntArray4( , ) as Integer =
    { {1, 2, 3},{4, 5, 6},{7, 8, 9},{10, 11, 12},{13, 14 , 15} }
ReDim arrMyIntArray5(2)
ReDim arrMyIntArray3(5,4)
ReDim Preserve arrMyIntArray4(UBound(arrMyIntArray4),1)

The ReDim of arrMyIntArray5 instantiates the elements of the array so that values can be assigned to each element. The second statement redimensions the arrMyIntArray3 variable defined earlier. Note that it is changing the size of both the first dimension and the second dimension. While it is not possible to change the number of dimensions in an array, you can resize any of an array's dimensions. This capability is required, as declarations such as Dim arrMyIntArray6( , , ,) As Integer are legal.

By the way, while it is possible to repeatedly ReDim a variable, for performance reasons this action should ideally be done only rarely, and never within a loop. If you intend to loop through a set of entries and add entries to an array, try to determine the number of entries you'll need before entering the loop, or at a minimum ReDim the size of your array in chunks to improve performance.

The Preserve Keyword

The last item in the code snippet in the preceding section illustrates an additional keyword associated with redimensioning. The Preserve keyword indicates that the data stored in the array prior to redimensioning should be transferred to the newly created array. If this keyword is not used, then the data stored in an array is lost. Additionally, in the preceding example, the ReDim statement actually reduces the second dimension of the array. Although this is a perfectly legal statement, this means that even though you have specified preserving the data, the data values 3, 6, 9, 12, and 15 that were assigned in the original definition of this array will be discarded. These are lost because they were assigned in the highest index of the second array. Because arrMyIntArray4(1,2) is no longer valid, the value that resided at this location (6) has been lost.

Arrays continue to be very powerful in Visual Basic, but the basic Array class is just that, basic. It provides a powerful framework, but it does not provide a lot of other features that would enable more robust logic to be built into the array. To achieve more advanced features, such as sorting and dynamic allocation, the base Array class has been inherited by the classes that make up the Collections namespace.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset