using System; using System.Collections.Generic; using System.Linq; using Chernobyl.Collections.Generic.Event; using Chernobyl.Event; using Chernobyl.Utility; namespace Chernobyl.Values { /// /// Holds the first item of an or /// default(T). If the first item in the /// changes, then the value held by this instance will be changed. /// /// The type being held within this instance. public class First : HeldValue { /// /// Initializes a new instance of the class. /// /// The that /// is to be watched for changes to its first item. /// Thrown if /// is null. public First(IEventEnumerable enumerable) : this(enumerable, EqualityComparer.Default) {} /// /// Initializes a new instance of the class. /// /// The that /// is to be watched for changes to its first item. /// The instance that is used to check if the /// instance's latest first is equal to it's /// previous first and therefore results in a change. /// Thrown if /// or is null. public First(IEventEnumerable enumerable, IEqualityComparer comparer) : base(default(T), comparer) { enumerable.ThrowIfNull("enumerable"); _enumerable = enumerable; Value = _enumerable.FirstOrDefault(); _enumerable.ItemsAdded += OnItemsAdded; _enumerable.ItemsRemoved += OnItemsRemoved; } /// /// An event that is invoked when an item is added to /// . This method invokes . /// /// The sender of the event. /// The instance containing the event data. void OnItemsAdded(object sender, ItemsEventArgs e) { Update(); } /// /// An event that is invoked when an item is removed from /// . This method invokes . /// /// The sender of the event. /// The instance containing the event data. void OnItemsRemoved(object sender, ItemsEventArgs e) { Update(); } /// /// Checks if the first item in the is /// different. /// void Update() { Value = _enumerable.FirstOrDefault(); } /// /// The that is to be watched for /// changes to its first item. /// readonly IEventEnumerable _enumerable; } /// /// Utility methods for or any code that uses /// . /// public static class FirstExtensions { /// /// Returns an instance that holds or will hold the first item of an /// . /// /// The type being held within this instance. /// The that /// is to be watched for changes to its first item. /// The instance that contains or will contain the first item. public static IValue First(this IEventEnumerable enumerable) { return new First(enumerable); } } }