Sunday, January 21, 2007

The magic yield return , Tree enumerators.

The yield return is a magic feature introduced in C# 2.0, it makes life lot easier to enumerate the collection. I was working on a tree collection recently, and it involves doing a BFS and DFS.

Here is the sample code..




538 /// <summary>


539 /// Gets the depth first node enumerator.


540 /// </summary>


541 /// <value>The depth first node enumerator.</value>


542 public IEnumerable<DTreeNode<T>> DepthFirstNodeEnumerator


543 {


544 get


545 {


546 yield return this;


547 if (m_Nodes != null)


548 {


549 foreach (DTreeNode<T> child in m_Nodes)


550 {


551 IEnumerator<DTreeNode<T>> childEnum = child.DepthFirstNodeEnumerator.GetEnumerator();


552 while (childEnum.MoveNext())


553 yield return childEnum.Current;


554 }


555 }


556 }


557 }


558


559 /// <summary>


560 /// Gets the breadth first node enumerator.


561 /// </summary>


562 /// <value>The breadth first node enumerator.</value>


563 public IEnumerable<DTreeNode<T>> BreadthFirstNodeEnumerator


564 {


565 get


566 {


567 Queue<DTreeNode<T>> todo = new Queue<DTreeNode<T>>();


568 todo.Enqueue(this);


569 while (0 < todo.Count)


570 {


571 DTreeNode<T> node = todo.Dequeue();


572 if (node.m_Nodes != null)


573 {


574 foreach (DTreeNode<T> child in node.m_Nodes)


575 todo.Enqueue(child);


576 }


577 yield return node;


578 }


579 }


580 }




The point of iterators is to allow the easy implementation of enumerators. Where a method needs to return either an enumerator or an enumerable class for an ordered list of items, it is written so as to return each item in its correct order using the ‘yield’ statement.

The magic yield will keep a state information in the enumeration, so it always remembers where to start in the next loop.

No comments: