21.3 Class Array and Enumerators

Chapter 8 presented basic array-processing capabilities. All arrays implicitly inherit from abstract base class Array (namespace System); this class defines property Length, which specifies the number of elements in the array. In addition, class Array provides static methods that provide algorithms for processing arrays. Typically, class Array overloads these methods—for example, Array method Reverse can reverse the order of the elements in an entire array or in a specified range of elements. For a complete list of class Array’s static methods visit


https://msdn.microsoft.com/library/system.array

Figure 21.3 demonstrates several static methods of class Array.

Fig. 21.3 Array class static methods for common array manipulations.

Alternate View

 1   // Fig. 21.3: UsingArray.cs
 2   // Array class static methods for common array manipulations.
 3   using System;
 4   using static System.Array;
 5 using System.Collections;
 6
 7   // demonstrate algorithms of class Array
 8   class UsingArray
 9   {
10      private static int[] intValues = {1, 2, 3, 4, 5, 6};
11      private static double[] doubleValues = {8.4, 9.3, 0.2, 7.9, 3.4};
12      private static int[] intValuesCopy;
13
14      // method Main demonstrates class Array's methods
15      static void Main()
16      {
17         intValuesCopy = new int[intValues.Length]; // defaults to zeroes
18
19         Console.WriteLine("Initial array values:
");
20         PrintArrays(); // output initial array contents
21
22         // sort doubleValues
23         Sort(doubleValues); // unqualified call to Array static method Sort
24
25         // copy intValues into intValuesCopy
26         Array.Copy(intValues, intValuesCopy, intValues.Length);
27
28         Console.WriteLine("
Array values after Sort and Copy:
");
29         PrintArrays(); // output array contents
30         Console.WriteLine();
31
32         // search for 5 in intValues
33         int result = Array.BinarySearch(intValues, 5);
34         Console.WriteLine(result >= 0 ?
35            $"5 found at element {result} in intValues" :
36            "5 not found in intValues");
37
38         // search for 8763 in intValues
39         result = Array.BinarySearch(intValues, 8763);
40         Console.WriteLine(result >= 0 ?
41            $"8763 found at element {result} in intValues" :
42            "8763 not found in intValues");
43      }
44
45      // output array content with enumerators
46      private static void PrintArrays()
47      {
48         Console.Write("doubleValues: ");
49
50         // iterate through the double array with an enumerator
51         IEnumerator enumerator = doubleValues.GetEnumerator();
52
53         while (enumerator.MoveNext())
54         {
55            Console.Write($"{enumerator.Current} ");
56         }
57
58         Console.Write("
intValues: ");
59
60         // iterate through the int array with an enumerator
61         enumerator = intValues.GetEnumerator();
62
63         while (enumerator.MoveNext())
64         {
65            Console.Write($"{enumerator.Current} ");
66         }
67
68         Console.Write("
intValuesCopy: ");
69
70         // iterate through the second int array with a foreach statement
71         foreach (var element in intValuesCopy)
72         {
73            Console.Write($"{element} ");
74         }
75
76         Console.WriteLine();
77      }
78   }

Initial array values:

doubleValues: 8.4 9.3 0.2 7.9 3.4
intValues: 1 2 3 4 5 6
intValuesCopy: 0 0 0 0 0 0

Array values after Sort and Copy:

doubleValues: 0.2 3.4 7.9 8.4 9.3
intValues: 1 2 3 4 5 6
intValuesCopy: 1 2 3 4 5 6

5 found at element 4 in intValues
8763 not found in intValues

21.3.1 C# 6 using static Directive

The using directives in lines 3 and 5 include the namespaces System (for classes Array and Console) and System.Collections (for interface IEnumerator, which we discuss shortly). Line 4 introduces C# 6’s using static directive for accessing a type’s static members without fully qualifying their names—in this case, class Array’s static members. Line 23


Sort(doubleValues); // unqualified call to Array static method Sort

shows an unqualified call to Array static method Sort, which is equivalent to


Array.Sort(doubleValues); // call to Array static method Sort

Though we could use unqualified calls for all of class Array’s static members in this example (e.g., Copy in line 26 and BinarySearch in lines 33 and 39), the code is easier to read with the fully qualified method calls, which make it absolutely clear which class contains a given static method.

21.3.2 Class UsingArray’s static Fields

Our test class declares three static array variables (lines 10–12). The first two lines initialize intValues and doubleValues to an int and double array, respectively. static variable intValuesCopy is intended to demonstrate the Array’s Copy method—it’s initially null, so it does not yet refer to an array.

Line 17 initializes intValuesCopy to an int array with the same length as array int-Values. Line 20 calls the PrintArrays method (lines 46–77) to output the initial contents of all three arrays. We discuss the PrintArrays method shortly. The output of Fig. 21.3 shows that each element of array intValuesCopy is initialized to the default value 0.

21.3.3 Array Method Sort

Line 23 uses static Array method Sort to sort array doubleValues in ascending order. The elements in the array must implement the IComparable interface (as all simple types do), which enables method Sort to compare elements to determine their order.

21.3.4 Array Method Copy

Line 26 uses static Array method Copy to copy elements from array intValues to array intValuesCopy. The first argument is the array to copy (intValues), the second argument is the destination array (intValuesCopy) and the third argument is an int representing the number of elements to copy (in this case, intValues.Length specifies all elements). Class Array also provides overloads for copying portions of arrays.

21.3.5 Array Method BinarySearch

Lines 33 and 39 invoke static Array method BinarySearch to perform binary searches on array intValues. Method BinarySearch receives the sorted array in which to search and the key for which to search. The method returns the index in the array at which it finds the key (or a negative number if the key was not found). BinarySearch assumes that it receives a sorted array. Its behavior on an unsorted array is undefined. Chapter 18 discussed binary searching in detail.

21.3.6 Array Method GetEnumerator and Interface IEnumerator

Method PrintArrays (lines 46–77) uses class Array’s methods to iterate over the elements of the arrays. Class Array implements the IEnumerable interface (the non-generic version of IEnumerable<T>). All arrays inherit implicitly from Array, so both the int[] and double[] array types implement IEnumerable interface method GetEnumerator, which returns an enumerator that can iterate over the collection—this method always returns an enumerator positioned before the first element. Interface IEnumerator (which all enumerators implement) defines methods MoveNext and Reset and property Current:

  • MoveNext moves the enumerator to the next element in the collection. The first call to MoveNext positions the enumerator at the first element of the collection—if there is an element, MoveNext returns true; otherwise, the method returns false.

  • Method Reset positions the enumerator before the first element of the collection.

  • Read-only property Current returns the object at the current location in the collection (determined by the last call to MoveNext).

Enumerators cannot be used to modify the contents of collections, only to obtain the contents.

Common Programming Error 21.1

If a collection is modified after an enumerator is created for that collection, the enumerator immediately becomes invalid—for this reason, enumerators are said to be “fail fast.” Any calls to the enumerator’s Reset or MoveNext methods after this point throw Invalid-OperationExceptions. This is true for collections, but not for arrays.

When an enumerator is returned by the GetEnumerator method in line 51, it’s initially positioned before the first element in Array doubleValues. Then when line 53 calls MoveNext in the first iteration of the while loop, the enumerator advances to the first element in doubleValues. The while statement in lines 53–56 iterates over each element until the enumerator passes the end of doubleValues and MoveNext returns false. In each iteration, we use the enumerator’s Current property to obtain and output the current array element. Lines 63–66 iterate over array intValues.

21.3.7 Iterating Over a Collection with foreach

Lines 71–74 use a foreach statement to iterate over the collection. Both foreach and an enumerator loop over the elements of an array one by one in consecutive order. Neither allows you to modify the elements during the iteration. This is not a coincidence. Every foreach statement implicitly obtains an enumerator via the GetEnumerator method and uses the enumerator’s MoveNext method and Current property to traverse the collection, just as we did explicitly in lines 51–56 and 61–66. For this reason, you should use the foreach statement to iterate over any collection that implements IEnumerable or IEnumerable<T>—as you saw for class List<T> in Section 9.4. Even class string implements IEnumerable<char> so you can iterate over a string’s characters.

21.3.8 Array Methods Clear, IndexOf, LastIndexOf and Reverse

Other static Array methods include:

  • Clear which sets a range of elements to 0, false or null, as appropriate.

  • IndexOf which locates the first occurrence of an object in an array or portion of an array.

  • LastIndexOf which locates the last occurrence of an object in an array or portion of an array.

  • Reverse which reverses the contents of an array or portion of an array.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset