March 5, 2011, 1:33 p.m.
posted by freeheart
Before we get to generic syntax, it makes sense to begin with the simplest collection: the array. An array is an indexed collection of objects, all of the same type (all ints, all strings, and so on). C# provides native syntax for the declaration of arrays. To picture a one-dimensional array, imagine a series of mailboxes, all lined up one after the other, as shown in Figure. Each mailbox can hold exactly one object (letter, box, and so on). Each mailbox also has a number, so you can identify which item is in which box. Unlike real-world mailboxes, though, all the mailboxes must hold the same kind of object; you declare the type of object that the mailboxes will hold when you declare the array.
An array of five integers
The important thing about arrays is that you can treat the entire array (the set of mailboxes) as a single entity, with a single name. As you'll see, using loops, you can easily perform an operation on every element within an array in turn.
Declare a C# array with the following syntax:
The square brackets () tell the C# compiler that you are declaring an array, and the type specifies the type of the elements it will contain. In the previous example, myIntArray is an array of integers.
Instantiate an array using the new keyword. For example:
myIntArray = new int;
This statement creates and intializes an array of five integers, all of which are initialized to the value zero.
It is important to distinguish between the array itself (which is a collection) and the elements held in the array (which can be of any type, so long as all the elements in the array are the same type). myIntArray is the array (or, more accurately, the variable that holds the reference to the array); its elements are the five integers it holds.
C# arrays are reference types, created on the heap. Thus, the array to which the variable myIntArray refers is allocated on the heap. The elements of an array are allocated based on their own type. Because integers are value types, the elements in myIntArray will be value types, and thus all the elements will be created inside the block of memory allocated for the array.
The block of memory allocated to an array of reference types will contain references to the actual elements, which are themselves created on the heap in memory separate from that allocated for the array.
Understanding Default Values
When you create an array of value types, each element initially contains the default value for the type stored in the array (see Figure). The statement:
myIntArray = new int;
creates an array of five integers, each of whose value is set to 0, which is the default value for integer types.
Unlike arrays of value types, the reference types in an array are not initialized to their default value. Instead, the references held in the array are initialized to null. If you attempt to access an element in an array of reference types before you have specifically initialized the elements, you will generate an exception.
Assume you have created a Button class. Declare an array of Button objects with the following statement:
and instantiate the actual array like this:
myButtonArray = new Button;
You can shorten this to:
Button myButtonArray = new Button;
This statement does not create an array with references to three Button objects. Instead, this creates the array myButtonArray with three null references. To use this array, you must first construct and assign the Button objects for each reference in the array. You can construct the objects in a loop that adds them one by one to the array, as you'll see later in the chapter.
Accessing Array Elements
You can access the elements of an array using the index operator (). Arrays are zero-based, which means that the index of the first element is always zeroin this case, myArray.
Figure illustrates the array concepts covered so far. In this example, a class named Tester creates an array of Employees and an array of integers, populates the Employee array, and then prints the values of both.
Working with an array
The output looks like this:
intArray values: 0 2 4 6 8 employee IDs: 1005 1006 1007
The example starts with the definition of an Employee class that implements a constructor that takes a single integer parameter. Employee implements the ToString( ) method to print the value of the Employee object's employee ID.
The test method declares and then instantiates a pair of arrays. Initially, the integer array is automatically filled with integers whose value is set to 0, but then you populate it with a for loop. The loop has a counter, i, and you iterate through the loop by setting each element of the array as the index value (i) increases. You set the value in intArray with this statement:
intArray[i] = i*2;
The first time through the loop, i is equal to 0, and intArray is set to 0*2, which is 0. The next time through, i is 1, and the second element (intArray) is set to the value 2 (1*2). The loop runs until i is equal to intArray.Length, at which point it stops. Note that i is equal to intArray.Length - 1 on the last time through the loop, which is the index of the last element in the array.
The Employee array contents must be constructed by hand, because the values of reference types are not initialized when the array is created (the array is filled with null values). You assign values to the elements of empArray the same way you did intArray, with a for loop. This time, though, you have to create a new Employee object to add to each index in the array
Finally, the contents of the arrays are displayed to ensure that they are filled as intended, using the same for loop technique. The five integers print their value first, followed by the three Employee objects.