using System.Collections.Generic; using Chernobyl.Collections.Generic.Event; using Chernobyl.Event; namespace Chernobyl.Collections.Generic { /// /// An that can iterate over a collection that /// changes, without throwing an exception. When the collection changes, this /// class is notified of it and grabs a new enumerator using /// . Note that, derived classes /// can override this behavior. /// /// The type being iterated over. public class DynamicEnumerator : IEnumerator { /// /// Initializes a new instance of the /// class. /// /// The event collection to iterate over. public DynamicEnumerator(DecoratingEventCollection decoratingEventCollection) { DecoratingEventCollection = decoratingEventCollection; DecoratingEventCollection.ItemsAdded += OnItemsAdded; DecoratingEventCollection.ItemsRemoved += OnItemsRemoved; } /// /// Called by this enumerator when the collection being iterated over /// has been changed. You can also call this method if you want to /// force this class to re-obtain the from /// the collection being iterated over. /// public virtual void CollectionChanged() { Enumerator = DecoratingEventCollection.GetEnumerator(); } /// /// Gets the element in the collection at the current position of the /// enumerator. /// /// /// The element in the collection at the current position of /// the enumerator. public T Current { get { return Enumerator.Current; } } /// /// Performs application-defined tasks associated with freeing, releasing, /// or resetting unmanaged resources. /// public void Dispose() { DecoratingEventCollection.ItemsAdded -= OnItemsAdded; DecoratingEventCollection.ItemsRemoved -= OnItemsRemoved; DecoratingEventCollection = null; Enumerator.Dispose(); } /// /// Advances the enumerator to the next element of the collection. /// /// /// true if the enumerator was successfully advanced to the next element; /// false if the enumerator has passed the end of the collection. /// /// The collection /// was modified after the enumerator was created. public bool MoveNext() { return Enumerator.MoveNext(); } /// /// Sets the enumerator to its initial position, which is before the /// first element in the collection. /// /// The collection /// was modified after the enumerator was created. public void Reset() { Enumerator.Reset(); } /// /// An event handler that is invoked when the collection being iterated /// over has items removed from it. This method, just calls /// . /// /// The sender. /// The /// instance containing the event data. protected virtual void OnItemsRemoved(object sender, ItemsEventArgs e) { CollectionChanged(); } /// /// An event handler that is invoked when the collection being iterated /// over has items added to it. This method, just calls /// . /// /// The sender. /// The /// instance containing the event data. protected virtual void OnItemsAdded(object sender, ItemsEventArgs e) { CollectionChanged(); } /// /// Gets the element in the collection at the current position of the /// enumerator. /// /// /// The element in the collection at the current position of /// the enumerator. object System.Collections.IEnumerator.Current { get { return Enumerator.Current; } } /// /// The being used to iterate over the /// collection. /// IEnumerator Enumerator { get; set; } /// /// The collection being iterated over. /// DecoratingEventCollection DecoratingEventCollection { get; set; } } }