6.6. Dealing with Finally Blocks and Iterators

Problem

You have added a try/finally block to your iterator, and you notice that the finally block is not being executed when you think it should.

Solution

Wrap a try block around the iteration code in the GetEnumerator iterator with a finally block following this try block:

	public class StringSet : IEnumerable<string>
	{
	    private List<string> _items = new List<string>();

	    public void Add(string value)
	    {
	        _items.Add(value);
	    }
	    public IEnumerator<string> GetEnumerator()
	    {
	        try
	        {
	            for (int index = 0; index < _items.Count; index++)
	            {
	                yield return (_items[index]);
	            }
	        }
	        finally
	        {
	            // Only executed at end of foreach loop (including on yield break)
	            Console.WriteLine("In iterator finally block");
	        }
	    }
	    #region IEnumerable Members

	    IEnumerator IEnumerable.GetEnumerator()
	    {
	        return GetEnumerator();
	    }


	    #endregion
	}

The foreach code that calls this iterator looks like this:

	//Create a StringSet object and fill it with data
	StringSet strSet =
	    new StringSet()
	        {"item1",
	         "item2",
	         "item3",
	         "item4",
	         "item5"};

	// Use the GetEnumerator iterator.
	foreach (string s in strSet)
	{
	    Console.WriteLine(s);
	}

When this code is run, the following output is displayed:

	item1
	item2
	item3
	item4
	item5
	In iterator finally block

Discussion

You may have thought that the output would display the "In iterator finally block" string after displaying each item in the strSet object. However, this is not the way that finally blocks are handled in iterators. All finally blocks associated with try blocks ...

Get C# 3.0 Cookbook, 3rd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.