0% found this document useful (0 votes)
64 views4 pages

Custom Iterators in C# Explained

The document discusses creating custom enumerators by implementing iterator methods on a Container class that contains a private list, allowing the class to be iterated over in different orders such as from first to last, last to first, or by skipping elements, providing flexibility beyond a standard enumerator. The Container class contains four iterator methods - GetEnumerator, ReverseOrder, ForwardOrderStep, and ReverseOrderStep - that yield elements from the private list in various looping patterns using parameters like iteration direction and step size. By implementing these custom iterators, the Container class provides rich enumeration capabilities beyond a basic enumerator.

Uploaded by

xact33
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
64 views4 pages

Custom Iterators in C# Explained

The document discusses creating custom enumerators by implementing iterator methods on a Container class that contains a private list, allowing the class to be iterated over in different orders such as from first to last, last to first, or by skipping elements, providing flexibility beyond a standard enumerator. The Container class contains four iterator methods - GetEnumerator, ReverseOrder, ForwardOrderStep, and ReverseOrderStep - that yield elements from the private list in various looping patterns using parameters like iteration direction and step size. By implementing these custom iterators, the Container class provides rich enumeration capabilities beyond a basic enumerator.

Uploaded by

xact33
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

C# Cookbook, 2nd Edition By Jay Hilyard, Stephen Teilhet ...............................................

Publisher: O'Reilly Pub Date: January 2006 Print ISBN-10: 0-596-10063-9 Print ISBN-13: 978-0-59-610063-6 Pages: 1184

Creating Custom Enumerators


Problem You need to add foreach support to a class, but the normal way of adding an iterator (i.e, implementing IEnumerable on a type and returning a reference to this IEnumerable from a member function) is not flexible enough. Instead of simply iterating from the first element to the last, you also need to iterate from the last to the first, and you need to be able to step over, or skip, a predefined number of elements on each iteration. You want to make all of these types of iterators available to your class. Solution The Container<T> class shown in Example 6-2 acts as a container for a private List<T> called internalList. Container is implemented so you can use it in a foreach loop to iterate through the private internalList.
Example 6-2. Creating custom iterators public class Container<T> { public Container() {} private List<T> internalList = new List<T>(); public List<T> List { set {internalList = value;} } // This iterator iterates over each element from first to last. public IEnumerator<T> GetEnumerator() { for (int index = 0; index < internalList.Count; index++) { yield return (internalList[index]); } }

// This iterator iterates over each element from last to first. public IEnumerable<T> ReverseOrder { get { for (int index = internalList.Count - 1; index >= 0; index--) { yield return (internalList[index]); } } } // This iterator iterates over each element from first to last stepping // over a predefined number of elements. public IEnumerable<T> ForwardOrderStep(int step) { for (int index = 0; index < internalList.Count; index += step) { yield return (internalList[index]); } } // This iterator iterates over each element from last to first stepping // over a predefined number of elements. public IEnumerable<T> ReverseOrderStep(int step) { for (int index = internalList.Count - 1; index >= 0; index -= step) { yield return (internalList[index]); } } }

Discussion Iterators provide an easy method of moving from item to item within an object using the familiar foreach loop construct. The object can be an array, a collection, or some other type of container. This is similar to using a for loop to manually iterate over each item contained in an array. In fact, an iterator can be set up to use a for loop, or any other looping construct for that matter, as the mechanism for yielding each item in the object. In fact, you do not even have to use a looping construct. The following code is perfectly valid:
public static IEnumerable<int> GetValues() { yield return 10;

yield return 20; yield return 30; yield return 100; }

With the foreach loop, you do not have to worry about moving the current element pointer to the beginning of the list or even about incrementing this pointer as you move through the list. In addition, you do not have to watch for the end of the list, since you cannot go beyond the bounds of the list. The best part about the foreach loop and iterators is that you do not have to know how to access the list of elements within its containerindeed, you do not even have to have access to the list of elements; the iterator member(s) implemented on the container do this for you. The Container class contains a private List of items called internalList. There are four iterator members within this class:
GetEnumerator ReverseOrder ForwardOrderStep ReverseOrderStep

The GetEnumerator method is implemented to return an IEnumerable<T>. This method iterates over each element in the internalList from the first to the last element. This iterator, similar to the others, uses a for loop to yield each element in the internalList. The ReverseOrder property implements an iterator in its get accessor (set accessors cannot be iterators). This iterator is very similar in design to the GetEnumerator method, except that the for loop works on the internalList in the reverse direction. Notice that even though this iterator is implemented as a property, there is no reason why it cannot be implemented as a method that takes no parameters. The last two iterators, ForwardOrderStep and ReverseOrderStep, are similar in design to GetEnumerator and ReverseOrder, respectively. The main difference (besides the fact that ReverseOrder is a property) is that the for loop uses the step parameter to skip over the specified number of items in the internalList. Notice also that only the GetEnumerator method must return an IEnumerator<T> interface; the other three iterators must return IEnumerable<T> interfaces. Using each of these iterators is extremely simple. To iterate over each element in the Container object from first to last, use the following code:
Container<int> cntnr = new Container<int>(); //Add data to cntnr here foreach (int i in cntnr) { Console.WriteLine(i);

To iterate over each element in the Container object from last to first, use the following code:
Container<int> cntnr = new Container<int>(); //Add data to cntnr here foreach (int i in cntnr.ReverseOrder) { Console.WriteLine(i); }

To iterate over each element in the Container object from first to last while skipping every other element, use the following code:
Container<int> cntnr = new Container<int>(); //Add data to cntnr here foreach (int i in cntnr.ForwardOrderStep(2)) { Console.WriteLine(i); }

To iterate over each element in the Container object from last to first while skipping to every third element, use the following code:
Container<int> cntnr = new Container<int>(); //Add data to cntnr here foreach (int i in cntnr.ReverseOrderStep(3)) { Console.WriteLine(i); }

In each of the last two examples, the iterator method accepts an integer value, step, that determines how many items will be skipped. See Also See the "Iterators," "yield," "IEnumerator Interface," and "IEnumerable Interface" topics in the MSDN documentation.

You might also like