The .NET Framework provides a rich suite of collection classes,
including Array
, ArrayList
,
NameValueCollection
,
StringCollection
, Queue
,
Stack
, and BitArray
.
The simplest collection is the Array
, the only
collection type for which C# provides built-in support. In this
chapter you will learn to work with single, multidimensional, and
jagged arrays. You will also be introduced to indexers, a bit of C#
syntactic sugar that makes it easier to access class properties, as
though the class were indexed like an array.
The .NET Framework provides a number of interfaces, such as
IEnumerable
and ICollection
,
whose implementation provides you with standard ways to interact with
collections. In this chapter you will see how to work with the most
essential of these. The chapter concludes with a tour of commonly
used .NET collections, including ArrayList
,
Dictionary
, Hashtable
,
Queue
, and Stack
.
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
You 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 example
above, myIntArray
is an array of integers.
You instantiate an array using the new
keyword.
For example:
myIntArray = new int[5];
This declaration sets aside memory for an array holding five integers.
Visual Basic programmers take note: the first
element is always 0; there is no way to set the upper or lower
bounds; and you cannot change the size (redim
) of
the array.
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.
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, “Primitive types and their default values”). The declaration:
myIntArray = new int[5];
creates an array of five integers, each of whose value is set to 0, 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. You
declare an array of Button
objects with the
following statement:
Button[] myButtonArray;
and you instantiate the actual array like this:
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.
You 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;
private int size;
}
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 zero. 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.
3.12.162.37