9.1. ArraysAn array is an indexed collection of objects, all of the same type. C# arrays are somewhat different from arrays in C++ because they are objects. This provides them with useful methods and properties. C# provides native syntax for the declaration of Arrays. What is actually created, however, is an object of type System.Array.[1] Arrays in C# thus provide you with the best of both worlds: easy-to-use C-style syntax underpinned with an actual class definition so that instances of an array have access to the methods and properties of System.Array. These appear in Table 9-1.
9.1.1. Declaring ArraysDeclare a C# array with the following syntax: type[] array-name; For example: int[] myIntArray;
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[5]; This declaration creates and initializes an array of five integers, all of which are initialized to the value 0.
string myArray[10];
It is important to distinguish between the array itself (which is a collection of elements) and the elements of the array. 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 myIntArray refers is allocated on the heap. The elements of an array are allocated based on their own type. Since integers are value types, the elements in myIntArray will be value types, not boxed integers, 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. 9.1.2. Understanding Default ValuesWhen you create an array of value types, each element initially contains the default value for the type stored in the array (refer back to Table 4-2). The statement: myIntArray = new int[5]; creates an array of five integers, each of whose value is set to 0, which is the default value for integer types. Unlike with arrays of value types, the reference types in an array aren't 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: Button[] myButtonArray; and instantiate the actual array like this: myButtonArray = new Button[3]; You can shorten this to: Button[] myButtonArray = new Button[3]; This statement doesn't 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. 9.1.3. Accessing Array ElementsAccess the elements of an array using the index operator ([]). Arrays are zero-based, which means that the index of the first element is always 0in this case, myArray[0]. As explained previously, arrays are objects and thus have properties. One of the more useful of these is Length, which tells you how many objects are in an array. Array objects can be indexed from 0 to Length-1. That is, if there are five elements in an array, their indexes are 0,1,2,3,4. Example 9-1 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. Example 9-1. Working with an arraynamespace Programming_CSharp { // a simple class to store in the array public class Employee { public Employee(int empID) { this.empID = empID; } public override string ToString( ) { return empID.ToString( ); } private int empID; } public class Tester { static void Main( ) { int[] intArray; Employee[] empArray; intArray = new int[5]; empArray = new Employee[3]; // populate the array for (int i = 0;i<empArray.Length;i++) { empArray[i] = new Employee(i+5); } for (int i = 0;i<intArray.Length;i++) { Console.WriteLine(intArray[i].ToString( )); } for (int i = 0;i<empArray.Length;i++) { Console.WriteLine(empArray[i].ToString( )); } } } } Output: 0 0 0 0 0 5 6 7 The example starts with the definition of an Employee class that implements a constructor that takes a single integer parameter. The ToString() method inherited from Object is overridden to print the value of the Employee object's employee ID. The test method declares and then instantiates a pair of arrays. The integer array is automatically filled with integers whose values are set to 0. The Employee array contents must be constructed by hand. Finally, the contents of the arrays are printed to ensure that they are filled as intended. The five integers print their value first, followed by the three Employee objects. |