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; }
}
}