Collections are groups of items; in .NET, collections contain objects (including boxed value types). Each object contained in a collection is called an element. Some collections contain a straightforward list of elements, while others (dictionaries) contain a list of key and value pairs. The following collection types consist of a straightforward list of elements:
ArrayList
|
BitArray
|
Queue
|
Stack
|
The following collection types are dictionaries:
Hashtable
|
SortedList
|
These collection classes are organized under the
System.Collections
namespace. In addition to this namespace, there is also another
namespace called System.Collections.Specialized
,
which contains a few more useful collection classes. These classes
might not be as well known as the previous classes, so here is a
short explanation of the list:
ListDictionary
This class operates very similar to the Hashtable
.
However, this class beats out the Hashtable
on
performance when it contains 10 or fewer elements.
HybridDictionary
This class consists of two internal collections, the
ListDictionary
and the
Hashtable
. Only one of these classes is used at
any one time. The ListDictionary
is used while the
collection contains 10 or fewer elements, and then a switch is made
to use a Hashtable
when the collection grows
beyond 10 elements. This switch is made transparently to the
developer. Once the Hashtable
is used, this
collection cannot revert to using the
ListDictionary
even if the elements number 10 or
fewer. Also note that when using strings as the key, this class
supports both case-sensitive (with respect to the invariant culture)
and case-insensitive string searches through setting a Boolean value
in the constructor.
CollectionsUtil
This class contains two static methods: one to create a
case-insensitive Hashtable
and another to create a
case-insensitive SortedList
. By directly creating
a Hashtable
and SortedList
object, you will always create a case-sensitive
Hashtable
or SortedList
, unless
you use one of the constructors that take an
IComparer
and pass
CaseInsensitiveComparer.Default
to it.
NameValueCollection
This collection consists of key and value pairs, which are both of
type String
. The interesting thing about this
collection is that it can store multiple string values with a single
key. The multiple string values are comma-delimited. The
String.Split
method is useful when breaking up
multiple strings in a value.
StringCollection
This collection is a simple list containing string elements. This
list accepts null
elements as well as duplicate
strings. This list is case-sensitive.
StringDictionary
This is a Hashtable
that stores both the key and
value as strings. Keys are converted to all lowercase letters before
being added to the Hashtable
, allowing for
case-insensitive comparisons. Keys cannot be null
,
but values may be set to null
.
The C# compiler also supports a fixed-size array. Arrays of any type may be created using the following syntax:
int[] foo = new int[2];
where foo
is an integer array containing exactly
2
elements.
Arrays come in several styles as well: multidimensional, jagged, and even multidimensional jagged. Multidimensional arrays are defined as shown here:
int[,] foo = new int[2,3]; // A 2-dimensional array containing up to 6 elements int[,,] bar = new int[2,3,4]; // A 3-dimensional array containing up to 24 elements
A two-dimensional array is usually described as a table with rows and
columns. The foo
array would be described as a
table of two rows each containing three columns of elements. A
three-dimensional array can be described as a cube with layers of
tables. The bar
array could be described as four
layers of two rows each containing three columns of elements.
Jagged arrays are arrays of arrays. Therefore, if you picture a jagged array as a type of two-dimensional array, it could have a different number of elements on each row. A jagged array is defined as follows:
int[][] baz = new int[2][] {new int[2], new int[3]};
The baz
array consists of a one-dimensional array
containing two elements. Each of these elements consists of another
array, the first array having two elements and the second array
having three.
The rest of this chapter contains recipes dealing with arrays and the various collection types.
Use a temporary object to hold one of the items being swapped:
public static void SwapElementsInArray(object[] theArray, int index1, int index2) { object tempHolder = theArray[index1]; theArray[index1] = theArray[index2]; theArray[index2] = tempHolder; }
You can make this method strongly typed by setting
theArray
parameter type to a specific type. The
following overload of the SwapElementsInArray
method has been modified to accept an array of integers. This fix
will prevent any costly boxing operations in the code that actually
swaps the two elements:
public static void SwapElementsInArray(int[] theArray, int index1, int index2) { int tempHolder = theArray[index1]; theArray[index1] = theArray[index2]; theArray[index2] = tempHolder; }
There is no specific method in the .NET Framework that allows only
two specific elements to be swapped within an array. The
SwapElementsInArray
method presented in this
recipe allows for only two specified elements of an array (specified
in the index1
and index2
arguments to this method).
The following code uses the SwapElementsInArray
method to swap the zeroth and fourth elements in an array of
integers:
public static void TestSwapArrayElements( ) { int[] someArray = new int[5] {1,2,3,4,5}; for (int counter = 0; counter < someArray.Length; counter++) { Console.WriteLine("Element " + counter + " = " + someArray[counter]); } SwapElementsInArray(someArray, 0, 4); for (int counter = 0; counter < someArray.Length; counter++) { Console.WriteLine("Element " + counter + " = " + someArray[counter]); } }
This code produces the following output:
Element 0 = 1 ← The original array Element 1 = 2 Element 2 = 3 Element 3 = 4 Element 4 = 5 Element 0 = 5 ← The array with reversed elements Element 1 = 2 Element 2 = 3 Element 3 = 4 Element 4 = 1