Fundamentals of .NET Support For Collections |
|
Enumerating the Members of a Collection |
Introduction to System Collections |
When studying arrays, we saw that you could use a for loop to visit each member of an array. This was also done with the help of the [] operator. In the previous lesson, we saw that, when creating a collection, you should provide a method that allows you to retrieve a member of the collection. In both cases, you can list the members of an array or a collection through a technique called an enumeration. Enumerating a collection consists of visiting each member of the list, for any reason judged necessary. For example, you can enumerate a collection to display a list of its members. You can enumerate a collection when looking for a member that responds to a certain criterion. Besides, or instead of a for loop, the .NET Framework provides another and better support for enumeration. In the C# language, you can enumerate a collection using the foreach operator, but the collection must be prepared for it: you cannot just use foreach for any collection. This support is provided through two main interfaces: IEnumerator and IEnumerable. These two interfaces are defined in the System.Collection namespace. Therefore, if you intend to use them, you can include this namespace in your source file. |
Practical Learning: Introducing Built-In Collections |
If your collection is an array-based list, you can start by declaring the base array in the class: Here is an example: public class Enumerator : IEnumerator { private double[] numbers; } If the collection is not array-based, you can declare a variable for the class that would be enumerated. The role of the enumerator is to act on a collection. For this reason, the class should be prepared to receive an external collection. This can be done by passing it to a constructor of the enumerator. Here is an example: public class Enumerator : IEnumerator { private double[] numbers; public Enumerator(double[] list) { } } The internal collection would be used in the enumerator class. The external collection would be the source of the values of the list that would be the enumerator. For these reasons, you can/should initialize the internal collection with the values of the external list. This can be done as follows: public class Enumerator : IEnumerator { private double[] numbers; public Enumerator(double[] list) { this.numbers = list; } }
In the previous lesson, when introducing some techniques of creating a list, we saw that you should have a type of tag, as a field, that allows you to monitor the item that is being currently accessed or used in the list. This is particularly valuable when visiting the members of the collection. The IEnumerator interface provides a property that is used to identify the current member of the list. This property is called Current. Because the current item is meant to be viewed only, the Current property is read-only. Based on the rules of abstract classes, remember that you must implement all members of an interface in the class that is based on it. To implement the Current property, you can implement its get accessor to return the item at the current position. This can be done as follows: public class Enumerator : IEnumerator { private double[] numbers; private int cur; public Enumerator(double[] list) { this.numbers = list; } public Object Current { get { return numbers[cur]; } } }
Although you should be able to identify the current item at any time, when the application starts, before the collection can be enumerated, the tag that is used to monitor the current item should be set to before the beginning of the count. This can be done by setting the tag to -1. Here is an example: public class Enumerator : IEnumerator { private double[] numbers; private int cur; public Enumerator(double[] list) { this.numbers = list; cur = -1; } public Object Current { get { return numbers[cur]; } } } While the collection is being, at one moment you may want to reset the tag of the current item to its original position. To support this operation, the IEnumerator is equipped with a method named Reset. Its syntax is: void Reset(); When implementing this method, simply assign a non-existing value, which is usually -1, to the monitoring tag of the current item. This can be done as follows: public class Enumerator : IEnumerator { private double[] numbers; private int cur; public Enumerator(double[] list) { this.numbers = list; cur = -1; } public Object Current { get { return numbers[cur]; } } public void Reset() { cur = -1; } } When using the implementer of the IEnumerator interface, if you try accessing an item beyond the maximum number of items, the compiler would throw an IndexOutOfRangeException exception. For this reason, when anticipating a bad behavior, you should catch this exception when implementing the Current property.
In the previous lesson, we saw that, when using the items of a collection, one way you can locate one item from another is to be able to jump from one item to the next. This operation is also very important when enumerating a collection. To support this operation, the IEnumerator is quipped with the MoveNext() method. Its syntax is: bool MoveNext(); When implementing this method, first increment the tag that monitors the current item of the collection. After incrementing the tag, check whether it is lower than the total number of items. If it is, return true. Otherwise, return false. This can be done as follows: public class Enumerator : IEnumerator { private double[] numbers; private int cur; public Enumerator(double[] list) { this.numbers = list; cur = -1; } public Object Current { get { return numbers[cur]; } } public void Reset() { cur = -1; } public bool MoveNext() { cur++; if (cur < numbers.Length) return true; else return false; } }
|
|
||
Previous | Copyright © 2006-2007 FunctionX, Inc. | Next |
|