Recipe6.6.Adding Multiple Iterators on a Single Type


Recipe 6.6. Adding Multiple Iterators on a Single Type

Problem

You need to add an iterator to a type that already implements the GetEnumerator iterator method; however, the iterators that you need to add are simple enough that they do not require parameters to be passed in to them as in Recipe 6.5. for example, the existing GetEnumerator iterator yields all elements in a forward-only order, but you also need to add an iterator that yields all elements in reverse order, an iterator that yields only the first half of the elements, and one that yields only the second half of the elements.

Solution

To add simple iterators that do not require parameters to be passed in to them, you can add properties with a get accessor. The get accessor must return an IEnumerable type and make use of the yield return statement. Example 6-4 shows one way to implement the solution.

Example 6-4. Adding multiple iterators that do not require parameters on a single type

 public class SimpleListIterator {     private List<string> _items = new List<string>();          public void AddItem(string item)     {         _items.Add(item);     }     public IEnumerator GetEnumerator()     {         for (int index = 0; index < _items.Count; index++)         {             yield return (_items[index]);         }     }     // Additional iterators implemented as property get accessors     public IEnumerable ReverseOrder     {         get         {             for (int index = _items.Count - 1; index >= 0; index--)             {                 yield return (_items[index]);             }         }     }     public IEnumerable FirstHalf     {         get         {             for (int index = 0; index < (_items.Count / 2); index++)             {                 yield return (_items[index]);             }         }     }     public IEnumerable SecondHalf     {         get         {             for (int index = (_items.Count / 2); index < _items.Count; index++)             {                 yield return (_items[index]);             }         }     } } 

Discussion

The SimpleListIterator class contains the typical GetEnumerator iterator method that yields all items in the _items list. In addition to this iterator method, the class contains three additional iterators: ReverseOrder, FirstHalf, and SecondHalf. The ReverseOrder iterator simply yields the elements in the _items list in reverse-index order, whereas the GetEnumerator method yields all elements in forward-index order. This is accomplished by setting up a for loop to start at either the zeroth element, for the GetEnumerator iterator method, or at the last element, as with the ReverseOrder iterator property.

The FirstHalf iterator property starts at the zeroth index of the _items list and yields all elements in the list up to the middle index. At this point iteration stops. The SecondHalf iterator property starts where the FirstHalf iterator property left off and continues yielding elements of the _items list until the end of this list.

The following code shows how the GetEnumerator iterator method is used, as well as the three iterator properties:

 public static void TestIteratorProperties() {     //Create SimpleListIterator object and fill it with data.     SimpleListIterator b = new SimpleListIterator();     b.AddItem("item1");     b.AddItem("item2");     b.AddItem("item3");     b.AddItem("item4");     b.AddItem("item5");     b.AddItem("item6");     b.AddItem("item7");     // Display all data in SimpleListIterator object.     Console.WriteLine("\r\nGetEnumerator iterator");     foreach (string s in b)     {         Console.WriteLine(s);     }     Console.WriteLine("\r\nReverseOrder iterator");     foreach (string s in b.ReverseOrder)     {         Console.WriteLine(s);     }     Console.WriteLine("\r\nFirstHalf iterator");     foreach (string s in b.FirstHalf)     {         Console.WriteLine(s);     }     Console.WriteLine("\r\nSecondHalf iterator");     foreach (string s in b.SecondHalf)     {         Console.WriteLine(s);     } } 

This code produces the following output:

 GetEnumerator iterator item1 item2 item3 item4 item5 item6 item7 ReverseOrder iterator item7 item6 item5 item4 item3 item2 item1 FirstHalf iterator item1 item2 item3 SecondHalf iterator item4 item5 item6 item7 

Notice that when using the GetEnumerator iterator, the foreach loop is set up as a typical foreach loop. However, when one of the iterator properties is used, the foreach loop is set up slightly differently. In this case, the iterator property's get accessor is actually called.

 foreach (string s in b.ReverseOrder) 

The iterator property returns an IEnumerable, which in turn is used by the foreach loop to obtain an IEnumerator.

See Also

See the "Iterators," "IEnumerator Interface," and "IEnumerable Interface" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net