Foreach Statement Calls Dispose() on IEnumerator

Again, something that might seems natural because you generally don’t see it or even think about it, but interesting to know.

If the IEnumerator/IEnumerator<T> returned by the GetEnumerator() function of a collection that is foreach-ed implements IDisposable, Dispose() will be called on it when the foreach is over.

Here is a sample code that does just that:

class Program
    {
        static void Main(string[] args)
        {
            foreach (var item in new SomeEnumerable())
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
        }

        class SomeEnumerable : IEnumerable<String>
        {
            #region IEnumerable<string> Members

            public IEnumerator<String> GetEnumerator()
            {
                return new CustomEnumerator(new List<String>() { "One", "Two" }.GetEnumerator());
            }

            #endregion

            #region IEnumerable Members

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

            #endregion

            class CustomEnumerator : IEnumerator<String>
            {
                IEnumerator<String> enumerator;

                public CustomEnumerator(IEnumerator<String> enumerator)
                {
                    this.enumerator = enumerator;
                }

                #region IEnumerator<string> Members

                public string Current
                {
                    get { return this.enumerator.Current; }
                }

                #endregion

                #region IDisposable Members

                public void Dispose()
                {
                    Console.WriteLine("SomeEnumerable Enumerator Disposed!");

                    this.enumerator.Dispose();
                }

                #endregion

                #region IEnumerator Members

                object System.Collections.IEnumerator.Current
                {
                    get { return this.enumerator.Current; }
                }

                public bool MoveNext()
                {
                    return this.enumerator.MoveNext();
                }

                public void Reset()
                {
                    this.enumerator.Reset();
                }

                #endregion
            }
        }
    }

You can look at the two possible code expansions for the foreach statement on the MSDN page.

Using Statement with an “expression”

Reading More Effective C# book, I was amazed to find out that the using statement can be used simply with an expression:

using-statement:
using ( resource-acquisition ) embedded-statement

resource-acquisition:
local-variable-declaration
expression

If the resource-acquisition is an expression, the variable resulting from the expression will be inaccessible to the embedded-statement.

Now, the reason why this is outlined in Bill Wagner’s book is when you write generic classes. Simply put, if expression is something like “a as IDisposable”, if a actually implements IDisposable, it will be disposed after the using statement. If it does not implements IDisposable, nothing will happen.

The beauty of this is that you don’t have to know, it will work in all cases.

I didn’t know that, and I find it very neat!