using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Chernobyl.Event; namespace Chernobyl.Collections.Generic.Event { /// /// An interface for working with types that /// allow client code to know when the has been /// modified. /// public interface IEventEnumerable : IEnumerable { /// /// An event that is raised right after items are added to this list. /// event EventHandler ItemsAdded; /// /// An event that is raised right after items are removed from this list. /// event EventHandler ItemsRemoved; } /// /// An interface for working with types that /// allow client code to know when the has been /// modified. /// /// The type that is to be held within the collection. public interface IEventEnumerable : IEnumerable, IEventEnumerable { /// /// An event that is raised right after items are added to this list. /// new event EventHandler> ItemsAdded; /// /// An event that is raised right after items are removed from this list. /// new event EventHandler> ItemsRemoved; } /// /// Utility methods for the type. /// public static class EventEnumerableExtensions { /// /// Invokes the when the first item has /// been added to . If an item is already /// in the list, then is invoked immediately. /// The method will not be invoked more /// than once. /// /// The type contained within the /// . /// The where /// the first item is to be found. /// The method that is to be invoked with the /// first item added to the or the first /// item found if the already has an item. public static void First(this IEventEnumerable enumerable, Action firstAdded) { if (enumerable.Any()) firstAdded(enumerable.First()); else { // We create a proxy method that 'wraps' the firstAdded method. // The proxy will remove itself from the IEventEnumerable.ItemsAdded // event of the enumerable so that firstAdded doesn't get called // more than once. EventHandler> proxy = null; proxy = (sender, e) => { firstAdded(e.Items[0]); enumerable.ItemsAdded -= proxy; }; enumerable.ItemsAdded += proxy; } } } }