Foreach Statement Calls Dispose() on IEnumerator
30 May 2010
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.
blog comments powered by Disqus