New Features in C# 2.0—GetEnumerator: How do I do that?
Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio
How do I do that?
As noted in the previous lab, the IEnumerable interface requires that you
implement only one method, GetEnumerator, as shown in Example 1-5.
Example 1-5. Enumerating through your linked list
using System; using System.Collections.Generic; namespace GenericEnumeration { public class Pilgrim : IComparable<Pilgrim> { private string name; public Pilgrim(string name) { this.name = name; } public override string ToString( ) { return this.name; } // implement the interface public int CompareTo(Pilgrim rhs) { return this.name.CompareTo(rhs.name); } public bool Equals(Pilgrim rhs) { return this.name = = rhs.name; } } // node must implement IComparable of Node of T // node now implements IEnumerable allowing its use // in a foreach loop public class Node<T> : IComparable<Node<T>>, IEnumerable<Node<T>> where T: IComparable<T> { // member fields private T data; private Node<T> next = null; private Node<T> prev = null; // constructor public Node(T data) { this.data = data; } // properties public T Data { get { return this.data; } } public Node<T> Next { get { return this.next; } } public int CompareTo(Node<T> rhs) { return data.CompareTo(rhs.data); } public bool Equals(Node<T> rhs) { return this.data.Equals(rhs.data); } // methods public Node<T> Add(Node<T> newNode) { if (this.CompareTo(newNode) > 0) // goes before me { newNode.next = this; // new node points to me // if I have a previous, set it to point to // the new node as its next if (this.prev != null) { this.prev.next = newNode; newNode.prev = this.prev; } // set prev in current node to point to new node this.prev = newNode; // return the newNode in case it is the new head return newNode; } else // goes after me { // if I have a next, pass the new node along for comparison if (this.next != null) { this.next.Add(newNode); } // I don't have a next so set the new node // to be my next and set its prev to point to me. else { this.next = newNode; newNode.prev = this; } return this; } } public override string ToString( ) { string output = data.ToString( ); if (next != null) { output += ", " + next.ToString( ); } return output; } // Method required by IEnumerable IEnumerator<Node<T>> IEnumerable<Node<T>>.GetEnumerator( ) { Node<T> nextNode = this; // iterate through all the nodes in the list // yielding each in turn do { Node<T> returnNode = nextNode; nextNode = nextNode.next; yield return returnNode; } while (nextNode != null); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new NotImplementedException(); } } // end class // implements IEnumerable so that you can use a LinkedList // in a foreach loop public class LinkedList<T> : IEnumerable<T> where T : IComparable<T> { // member fields private Node<T> headNode = null; // properties // indexer public T this[int index] { get { int ctr = 0; Node<T> node = headNode; while (node != null && ctr <= index) { if (ctr = = index) { return node.Data; } else { node = node.Next; } ++ctr; } // end while throw new ArgumentOutOfRangeException( ); } // end get } // end indexer // constructor public LinkedList() { } // methods public void Add(T data) { if (headNode = = null) { headNode = new Node<T>(data); } else { headNode = headNode.Add(new Node<T>(data)); } } public override string ToString( ) { if (this.headNode != null) { return this.headNode.ToString( ); } else { return string.Empty; } } // Implement IEnumerable required method // iterate through the node (which is enumerable) // and yield up the data from each node returned IEnumerator<T> IEnumerable<T>.GetEnumerator( ) { foreach (Node<T> node in this.headNode) { yield return node.Data; } } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new NotImplementedException(); } } class Program { private static void DisplayList<T> (string intro, LinkedList<T> theList) where T : IComparable<T> { Console.WriteLine(intro + ": " + theList); } // entry point static void Main(string[ ] args) { LinkedList<Pilgrim> pilgrims = new LinkedList<Pilgrim>( ); pilgrims.Add(new Pilgrim("The Knight")); pilgrims.Add(new Pilgrim("The Miller")); pilgrims.Add(new Pilgrim("The Reeve")); pilgrims.Add(new Pilgrim("The Cook")); pilgrims.Add(new Pilgrim("The Man of Law")); DisplayList<Pilgrim>("Pilgrims", pilgrims); Console.WriteLine("Iterate through pilgrims..."); // Now that the linked list is enumerable, we can put // it into a foreach loop foreach (Pilgrim p in pilgrims) { Console.WriteLine("The pilgrim's name is " + p.ToString( )); } } } }
Output:
Pilgrims: The Cook, The Knight, The Man of Law, The Miller, The Reeve
Iterate through pilgrims...
The pilgrim's name is The Cook
The pilgrim's name is The Knight
The pilgrim's name is The Man of Law
The pilgrim's name is The Miller
The pilgrim's name is The Reeve
|

