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