Simple Arrays
If you need to use multiple objects of the
same type, you can use an array. An array is a data structure that
contains a number of elements of the same type.
Array Declaration
An array is declared by defining the type of
the elements inside the array followed by empty brackets and a
variable name; for example, an array containing integer elements is
declared like this:
Array Initialization
After declaring an array, memory must be
allocated to hold all the elements of the array. An array is a
reference type, so memory on the heap must be allocated. This is
done by initializing the variable of the array using the
new operator with the type and the
number of elements inside the array. Here you specify the size of
the array.
With this declaration and initialization, the
variable myArray references four integer
values that are allocated on the managed heap (see Figure 5-1).
|
|
Important |
The array cannot be resized after the size
was specified without copying all elements. If you don’t know the
number of elements that should be in the array in advance, you can
use a collection. Collections are covered in Chapter
10, “Collections.”
|
Instead of using a separate line for the
declaration and initialization, you can declare and initialize an
array in a single line:
You can also assign values to every array element
using an array initializer. Array initializers can only be used
while declaring an array variable, not after the array is
declared.
If you initialize the array using curly brackets,
the size of the array can also be left out, as the compiler can
count the number of elements itself:
There’s even a shorter form using the C# compiler.
Using curly brackets you can write the array declaration and
initialization. The code generated from the compiler as the same as
in the previous example.
Accessing Array Elements
After an array is declared and initialized,
you can access the array elements using an indexer. Arrays only
support indexers that have integer parameters.
|
|
Tip |
With custom classes, you can also create
indexers that support other types. You can read about creating
custom indexers in Chapter 6, “Operators and Casts.
|
With the indexer, you pass the element number to
access the array. The indexer always starts with a value of 0 for
the first element. The highest number you can pass to the indexer
is the number of elements minus one, since the index starts at
zero. In the following example, the array myArray is declared and initialized with four
integer values. The elements can be accessed with indexer values 0,
1, 2 and 3.
|
|
Important |
If you use a wrong indexer value where no
element exists, an exception of type IndexOutOfRangeException is thrown.
|
If you don’t know the number of elements in the
array, you can use the Length property
that is used in this for statement:
Instead of using a for
statement to iterate through all elements of the array, you can
also use the foreach statement.
|
|
Tip |
The foreach
statement makes use of the IEnumerable
and IEnumerator interfaces that are
discussed later in this chapter.
|
Using Reference Types
You cannot only declare arrays of predefined
types; you can also declare arrays of a type of a custom class.
Let’s start with this Person class with
two constructors, the properties Firstname and Lastname,
and an override of the ToString()
method:
Declaring an array of two Person elements is similar to declaring an array of
int:
However, you must be aware that if the elements in
the array are reference types, memory must be allocated for every
array element. In case you use an item in the array where no memory
was allocated, a NullReferenceException
is thrown.
You can allocate every element of the array by
using an indexer starting from 0:
Figure 5-2
shows the objects in the managed heap with the Person array. myPersons
is a variable that is stored on the stack. This variable references
an array of Person elements that is
stored on the managed heap. This array has enough space for two
references. Every item in the array references a Person object that is also stored in the managed
heap.
As you’ve seen it with the int type, you can also use an array initializer with
custom types:
|