Recipe6.4.Creating an Iterator on a Non-generic Type


Recipe 6.4. Creating an Iterator on a Non-generic Type

Problem

You want elements contained in your non-generic type to be enumerated using the foreach statement.

Solution

Add an iterator to your non-generic type, as shown here:

 public class NGShoppingList {     public NGShoppingList() {}     private List<string> _items = new List<string>();     public void AddItem(string item)     {         _items.Add(item);     }     public IEnumerator<string> GetEnumerator()     {         for (int index = 0; index < _items.Count; index++)         {             yield return (_items[index]);         }     } } 

The following code creates a new NGShoppingList object and fills it with strings; it then proceeds to use a foreach loop to enumerate and display each string:

 public static void TestShoppingCart() {     // Create NGShoppingList object and fill it with data.     NGShoppingList scart = new NGShoppingList();     scart.AddItem("item1");     scart.AddItem("item2");     scart.AddItem("item3");     scart.AddItem("item4");     scart.AddItem("item5");     scart.AddItem("item6");     // Display all data in NGShoppingCart object.     foreach(string s in scart)     {         Console.WriteLine(s);     } } 

Discussion

Adding an iterator to a type is fairly straightforward. You simply add a GetEnumerator method that accepts no arguments and returns an IEnumerator<string> type. In addition to this, the enumerator must have public accessibility. This GetEnumerator method is called by the foreach loop to determine what object is returned by this loop on every iteration.

The code that you write inside of the GetEnumerator method is what actually does the work of determining the next object to be returned by the foreach loop. This is accomplished through the use of the yield return statement. For example, in this recipe you simply use a for loop to iterate over each item in the _items List<string> and display each item in turn from the first to the last.

This is all the work that the developer has to do; the rest is performed by the C# compiler. The compiler takes this code and from it creates a class that is nested within the NGShoppingList class, which contains a simple state machine. This state machine is based on the code within the GetEnumerator method.

Notice that the IEnumerable interface was not explicitly implemented on the NGShoppingList class. It is optional for you to explicitly implement this interface. Whether you choose to implement this interface or not, the final behavior of the NGShoppingList class iterator is the same.

If you choose to implement the IEnumerator interface on the NGShoppingList class, the class declaration will change to look like this:

 public class NGShoppingList : IEnumerable  

Regardless of the method you choose, the operation of the iterator and the foreach loop is identical.

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