[ Team LiB ] Previous Section Next Section

9.1 Arrays

An array is an indexed collection of objects, all of the same type. C# arrays are somewhat different from arrays in C++ and other languages, because they are objects. This provides them with useful methods and properties.

C# provides native syntax for the declaration of Array objects. What is actually created, however, is an object of type System.Array. 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.

Table 9-1. System.Array methods and properties

Method or property

Purpose

BinarySearch( )

Overloaded public static method that searches a one-dimensional sorted array.

Clear( )

Public static method that sets a range of elements in the array either to zero or to a null reference.

Copy( )

Overloaded public static method that copies a section of one array to another array.

CreateInstance( )

Overloaded public static method that instantiates a new instance of an array.

IndexOf( )

Overloaded public static method that returns the index (offset) of the first instance of a value in a one-dimensional array.

LastIndexOf( )

Overloaded public static method that returns the index of the last instance of a value in a one-dimensional array.

Reverse( )

Overloaded public static method that reverses the order of the elements in a one-dimensional array.

Sort( )

Overloaded public static method that sorts the values in a one-dimensional array.

IsFixedSize

Public property that returns a value indicating whether the array has a fixed size.

IsReadOnly

Public property that returns a Boolean value indicating whether the array is read-only.

IsSynchronized

Public property that returns a Boolean value indicating whether the array is thread-safe.

Length

Public property that returns the length of the array.

Rank

Public property that returns the number of dimensions of the array.

SyncRoot

Public property that returns an object that can be used to synchronize access to the array.

GetEnumerator( )

Public method that returns an IEnumerator.

GetLength( )

Public method that returns the length of the specified dimension in the array.

GetLowerBound( )

Public method that returns the lower boundary of the specified dimension of the array.

GetUpperBound( )

Public method that returns the upper boundary of the specified dimension of the array.

Initialize( )

Initializes all values in a value type array by calling the default constructor for each value.

SetValue( )

Overloaded public method that sets the specified array elements to a value.

9.1.1 Declaring Arrays

Declare 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 sets aside memory for an array holding five integers.

VB6 programmers take note: In C#, the value of the size of the array marks the number of elements in the array, not the upper bound. In fact, there is no way to set the upper or lower bounds. Moreover, the first element is always 0. Thus the following C# statement declares an array of 10 elements, with indices 0 through 9:

   string myArray[10];

The upper bound is 9, not 10, and you cannot change the size of the array (that is, there is no equivalent to the VB6 Redim function).

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; its elements are the five integers it holds. C# arrays are reference types, created on the heap. Thus, myIntArray is allocated on the heap. The elements of an array are allocated based on their type. Integers are value types, and so the elements in myIntArray will be value types, not boxed integers. An array of reference types will contain nothing but references to the elements, which are themselves created on the heap.

9.1.2 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 Table 4-2). The declaration:

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 are not initialized to their default value. Instead, they are initialized to null. If you attempt to access an element in an array of reference types before you have specifically initialized them, 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];

Unlike with the earlier integer example, 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.

9.1.3 Accessing Array Elements

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 zero—in 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 indices 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 array
namespace Programming_CSharp
{
   using System;
  
   // a simple class to store in the array
   public class Employee
   {
      // a simple class to store in the array
      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 value is 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.

    [ Team LiB ] Previous Section Next Section